Re: [PATCH] EFI loader: remove dead code

2016-11-01 Thread Linn Crosetto
On Tue, Nov 01, 2016 at 08:38:08PM +0300, Eugene Korenevsky wrote:
> *e820ext is always NULL in 'alloc_e820ext()' (see the code of 'exit_boot()').
> Therefore the 'if' condition is always false and the entire 'if' statement is
> pointless. Remove it.
> 
> ---
>  arch/x86/boot/compressed/eboot.c | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/arch/x86/boot/compressed/eboot.c 
> b/arch/x86/boot/compressed/eboot.c
> index cc69e37..edfd4d6 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -956,12 +956,6 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct 
> setup_data **e820ext,
>   size = sizeof(struct setup_data) +
>   sizeof(struct e820entry) * nr_desc;
>  
> - if (*e820ext) {
> - efi_call_early(free_pool, *e820ext);
> - *e820ext = NULL;
> - *e820ext_size = 0;
> - }
> -

I agree with your reading of the code. On the other hand, alloc_e820ext()
has no knowledge of the 'first' flag used in exit_boot_func() so the call to
free provides some assurance that memory isn't leaked if the calling code is
changed.

If the caller is responsible for freeing the memory in such a case, then
alloc_e820ext() should at least return an error.

--
Linn


Re: [PATCH] EFI loader: remove dead code

2016-11-01 Thread Linn Crosetto
On Tue, Nov 01, 2016 at 08:38:08PM +0300, Eugene Korenevsky wrote:
> *e820ext is always NULL in 'alloc_e820ext()' (see the code of 'exit_boot()').
> Therefore the 'if' condition is always false and the entire 'if' statement is
> pointless. Remove it.
> 
> ---
>  arch/x86/boot/compressed/eboot.c | 6 --
>  1 file changed, 6 deletions(-)
> 
> diff --git a/arch/x86/boot/compressed/eboot.c 
> b/arch/x86/boot/compressed/eboot.c
> index cc69e37..edfd4d6 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -956,12 +956,6 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct 
> setup_data **e820ext,
>   size = sizeof(struct setup_data) +
>   sizeof(struct e820entry) * nr_desc;
>  
> - if (*e820ext) {
> - efi_call_early(free_pool, *e820ext);
> - *e820ext = NULL;
> - *e820ext_size = 0;
> - }
> -

I agree with your reading of the code. On the other hand, alloc_e820ext()
has no knowledge of the 'first' flag used in exit_boot_func() so the call to
free provides some assurance that memory isn't leaked if the calling code is
changed.

If the caller is responsible for freeing the memory in such a case, then
alloc_e820ext() should at least return an error.

--
Linn


[tip:efi/core] efi/arm64: Check SetupMode when determining Secure Boot status

2016-04-28 Thread tip-bot for Linn Crosetto
Commit-ID:  30d7bf034c034995f34dae265d96247f7f12044e
Gitweb: http://git.kernel.org/tip/30d7bf034c034995f34dae265d96247f7f12044e
Author: Linn Crosetto <l...@hpe.com>
AuthorDate: Mon, 25 Apr 2016 21:06:37 +0100
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 28 Apr 2016 11:33:49 +0200

efi/arm64: Check SetupMode when determining Secure Boot status

According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot.

Plus also do minor cleanup, change sizeof() use to match kernel style 
guidelines.

Signed-off-by: Linn Crosetto <l...@hpe.com>
Signed-off-by: Matt Fleming <m...@codeblueprint.co.uk>
Reviewed-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Acked-by: Mark Rutland <mark.rutl...@arm.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Roy Franz <roy.fr...@linaro.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: linux-...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1461614832-17633-6-git-send-email-m...@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 07f967c..1286325 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -22,21 +22,39 @@ bool __nokaslr;
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:


[tip:efi/core] efi/arm64: Check SetupMode when determining Secure Boot status

2016-04-28 Thread tip-bot for Linn Crosetto
Commit-ID:  30d7bf034c034995f34dae265d96247f7f12044e
Gitweb: http://git.kernel.org/tip/30d7bf034c034995f34dae265d96247f7f12044e
Author: Linn Crosetto 
AuthorDate: Mon, 25 Apr 2016 21:06:37 +0100
Committer:  Ingo Molnar 
CommitDate: Thu, 28 Apr 2016 11:33:49 +0200

efi/arm64: Check SetupMode when determining Secure Boot status

According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot.

Plus also do minor cleanup, change sizeof() use to match kernel style 
guidelines.

Signed-off-by: Linn Crosetto 
Signed-off-by: Matt Fleming 
Reviewed-by: Ard Biesheuvel 
Acked-by: Mark Rutland 
Cc: Borislav Petkov 
Cc: Peter Zijlstra 
Cc: Roy Franz 
Cc: Thomas Gleixner 
Cc: linux-...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1461614832-17633-6-git-send-email-m...@codeblueprint.co.uk
Signed-off-by: Ingo Molnar 
---
 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 07f967c..1286325 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -22,21 +22,39 @@ bool __nokaslr;
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:


[tip:efi/core] efi/arm64: Report unexpected errors when determining Secure Boot status

2016-04-28 Thread tip-bot for Linn Crosetto
Commit-ID:  73a6492589c87cd56707c8ac19eec78236c2d576
Gitweb: http://git.kernel.org/tip/73a6492589c87cd56707c8ac19eec78236c2d576
Author: Linn Crosetto <l...@hpe.com>
AuthorDate: Mon, 25 Apr 2016 21:06:36 +0100
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 28 Apr 2016 11:33:48 +0200

efi/arm64: Report unexpected errors when determining Secure Boot status

Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable() when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto <l...@hpe.com>
Signed-off-by: Matt Fleming <m...@codeblueprint.co.uk>
Reviewed-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
Acked-by: Mark Rutland <mark.rutl...@arm.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Roy Franz <roy.fr...@linaro.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: linux-...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1461614832-17633-5-git-send-email-m...@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 drivers/firmware/efi/libstub/arm-stub.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 414deb8..07f967c 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,7 +20,7 @@
 
 bool __nokaslr;
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -39,8 +39,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -185,6 +189,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -250,12 +255,21 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
+   if (secure_boot < 0) {
+   pr_efi_err(sys_table,
+   "could not determine UEFI Secure Boot status.\n");
+   }
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+   if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) {
+   pr_efi(sys_table, "Ignoring DTB from command line.\n");
} else {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",


[tip:efi/core] efi/arm64: Report unexpected errors when determining Secure Boot status

2016-04-28 Thread tip-bot for Linn Crosetto
Commit-ID:  73a6492589c87cd56707c8ac19eec78236c2d576
Gitweb: http://git.kernel.org/tip/73a6492589c87cd56707c8ac19eec78236c2d576
Author: Linn Crosetto 
AuthorDate: Mon, 25 Apr 2016 21:06:36 +0100
Committer:  Ingo Molnar 
CommitDate: Thu, 28 Apr 2016 11:33:48 +0200

efi/arm64: Report unexpected errors when determining Secure Boot status

Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable() when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto 
Signed-off-by: Matt Fleming 
Reviewed-by: Ard Biesheuvel 
Acked-by: Mark Rutland 
Cc: Borislav Petkov 
Cc: Peter Zijlstra 
Cc: Roy Franz 
Cc: Thomas Gleixner 
Cc: linux-...@vger.kernel.org
Link: 
http://lkml.kernel.org/r/1461614832-17633-5-git-send-email-m...@codeblueprint.co.uk
Signed-off-by: Ingo Molnar 
---
 drivers/firmware/efi/libstub/arm-stub.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 414deb8..07f967c 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,7 +20,7 @@
 
 bool __nokaslr;
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -39,8 +39,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -185,6 +189,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -250,12 +255,21 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
+   if (secure_boot < 0) {
+   pr_efi_err(sys_table,
+   "could not determine UEFI Secure Boot status.\n");
+   }
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+   if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) {
+   pr_efi(sys_table, "Ignoring DTB from command line.\n");
} else {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",


[PATCH v3 1/2] arm64/efi: report unexpected errors when determining Secure Boot status

2016-03-03 Thread Linn Crosetto
Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable() when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto <l...@hpe.com>
---
v2:
 - Maintain existing behavior to allow 'dtb=' parameter only when UEFI
   Secure Boot is disabled and not in an unknown state. (Mark Rutland)

v3:
 - Add prints to inform the user in the following two cases: failure to
   determine Secure Boot status, ignoring "dtb=" kernel parameter (Ard
   Biesheuvel)

 drivers/firmware/efi/libstub/arm-stub.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..1e98fb7 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -18,7 +18,7 @@
 
 #include "efistub.h"
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -37,8 +37,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -183,6 +187,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -231,12 +236,21 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
+   if (secure_boot < 0) {
+   pr_efi_err(sys_table,
+   "could not determine UEFI Secure Boot status.\n");
+   }
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+   if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) {
+   pr_efi(sys_table, "Ignoring DTB from command line.\n");
} else {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",
-- 
2.1.4



[PATCH v3 1/2] arm64/efi: report unexpected errors when determining Secure Boot status

2016-03-03 Thread Linn Crosetto
Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable() when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto 
---
v2:
 - Maintain existing behavior to allow 'dtb=' parameter only when UEFI
   Secure Boot is disabled and not in an unknown state. (Mark Rutland)

v3:
 - Add prints to inform the user in the following two cases: failure to
   determine Secure Boot status, ignoring "dtb=" kernel parameter (Ard
   Biesheuvel)

 drivers/firmware/efi/libstub/arm-stub.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..1e98fb7 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -18,7 +18,7 @@
 
 #include "efistub.h"
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -37,8 +37,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -183,6 +187,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -231,12 +236,21 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
+   if (secure_boot < 0) {
+   pr_efi_err(sys_table,
+   "could not determine UEFI Secure Boot status.\n");
+   }
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+   if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) {
+   pr_efi(sys_table, "Ignoring DTB from command line.\n");
} else {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",
-- 
2.1.4



[PATCH v3 2/2] arm64/efi: check SetupMode when determining Secure Boot status

2016-03-03 Thread Linn Crosetto
According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot. Minor cleanup, change sizeof to match kernel style guidelines.

Signed-off-by: Linn Crosetto <l...@hpe.com>
---
v2:
 - Reformat quote from UEFI specification and note cleanup (Mark Rutland)
 - Restructure code on top of changes in patch 1/2

 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 1e98fb7..c049d41 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,21 +20,39 @@
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:
-- 
2.1.4



[PATCH v3 2/2] arm64/efi: check SetupMode when determining Secure Boot status

2016-03-03 Thread Linn Crosetto
According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot. Minor cleanup, change sizeof to match kernel style guidelines.

Signed-off-by: Linn Crosetto 
---
v2:
 - Reformat quote from UEFI specification and note cleanup (Mark Rutland)
 - Restructure code on top of changes in patch 1/2

 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 1e98fb7..c049d41 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,21 +20,39 @@
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:
-- 
2.1.4



[PATCH v3 0/2] arm64/efi: query Secure Boot status according to UEFI spec

2016-03-03 Thread Linn Crosetto
This series modifies the function that queries the status of UEFI Secure Boot
in the EFI stub to match the UEFI specification, and allow the caller to
determine if it is enabled, disabled, or in an unknown state due to an
unexpected error from GetVariable().

v2:
 - Add return values for unexpected errors
 - Split changes into two patches

v3:
 - Add more verbosity with additional prints

Linn Crosetto (2):
  arm64/efi: report unexpected errors when determining Secure Boot status
  arm64/efi: check SetupMode when determining Secure Boot status

 drivers/firmware/efi/libstub/arm-stub.c | 54 ++---
 1 file changed, 43 insertions(+), 11 deletions(-)

-- 
2.1.4



[PATCH v3 0/2] arm64/efi: query Secure Boot status according to UEFI spec

2016-03-03 Thread Linn Crosetto
This series modifies the function that queries the status of UEFI Secure Boot
in the EFI stub to match the UEFI specification, and allow the caller to
determine if it is enabled, disabled, or in an unknown state due to an
unexpected error from GetVariable().

v2:
 - Add return values for unexpected errors
 - Split changes into two patches

v3:
 - Add more verbosity with additional prints

Linn Crosetto (2):
  arm64/efi: report unexpected errors when determining Secure Boot status
  arm64/efi: check SetupMode when determining Secure Boot status

 drivers/firmware/efi/libstub/arm-stub.c | 54 ++---
 1 file changed, 43 insertions(+), 11 deletions(-)

-- 
2.1.4



[PATCH v2 2/2] arm64/efi: check SetupMode when determining Secure Boot status

2016-02-25 Thread Linn Crosetto
According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot. Minor cleanup, change sizeof to match kernel style guidelines.

Signed-off-by: Linn Crosetto <l...@hpe.com>
---
v2:

 - Reformat quote from UEFI specification and note cleanup (Mark Rutland)
 - Restructure code on top of changes in patch 1/2

 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index b1bb133..19e54d4 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,21 +20,39 @@
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:
-- 
2.1.4



[PATCH v2 2/2] arm64/efi: check SetupMode when determining Secure Boot status

2016-02-25 Thread Linn Crosetto
According to the UEFI specification (version 2.5 Errata A, page 87):

The platform firmware is operating in secure boot mode if the value of
the SetupMode variable is 0 and the SecureBoot variable is set to 1. A
platform cannot operate in secure boot mode if the SetupMode variable
is set to 1.

Check the value of the SetupMode variable when determining the state of
Secure Boot. Minor cleanup, change sizeof to match kernel style guidelines.

Signed-off-by: Linn Crosetto 
---
v2:

 - Reformat quote from UEFI specification and note cleanup (Mark Rutland)
 - Restructure code on top of changes in patch 1/2

 drivers/firmware/efi/libstub/arm-stub.c | 32 +---
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index b1bb133..19e54d4 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,21 +20,39 @@
 
 static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   goto out_efi_err;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
+
+out_efi_err:
switch (status) {
-   case EFI_SUCCESS:
-   return val;
case EFI_NOT_FOUND:
return 0;
case EFI_DEVICE_ERROR:
-- 
2.1.4



[PATCH v2 0/2] arm64/efi: query Secure Boot status according to UEFI spec

2016-02-25 Thread Linn Crosetto
This series modifies the function that queries the status of UEFI Secure Boot
in the EFI stub to match the UEFI specification, and allow the caller to
determine if it is enabled, disabled, or in an unknown state due to an
unexpected error from GetVariable().

v2:

 - Add return values for unexpected errors
 - Split changes into two patches

Linn Crosetto (2):
  arm64/efi: report unexpected errors when determining Secure Boot status
  arm64/efi: check SetupMode when determining Secure Boot status

 drivers/firmware/efi/libstub/arm-stub.c | 49 +
 1 file changed, 37 insertions(+), 12 deletions(-)

-- 
2.1.4



[PATCH v2 1/2] arm64/efi: report unexpected errors when determining Secure Boot status

2016-02-25 Thread Linn Crosetto
Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto <l...@hpe.com>
---
New patch in v2 based on feedback from v1:

 - Maintain existing behavior to allow 'dtb=' parameter only when UEFI
   Secure Boot is disabled and not in an unknown state. (Mark Rutland)

 drivers/firmware/efi/libstub/arm-stub.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..b1bb133 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -18,7 +18,7 @@
 
 #include "efistub.h"
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -37,8 +37,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -183,6 +187,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -231,13 +236,15 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
-   } else {
+   if (secure_boot == 0) {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",
  ~0UL, _addr, _size);
-- 
2.1.4



[PATCH v2 0/2] arm64/efi: query Secure Boot status according to UEFI spec

2016-02-25 Thread Linn Crosetto
This series modifies the function that queries the status of UEFI Secure Boot
in the EFI stub to match the UEFI specification, and allow the caller to
determine if it is enabled, disabled, or in an unknown state due to an
unexpected error from GetVariable().

v2:

 - Add return values for unexpected errors
 - Split changes into two patches

Linn Crosetto (2):
  arm64/efi: report unexpected errors when determining Secure Boot status
  arm64/efi: check SetupMode when determining Secure Boot status

 drivers/firmware/efi/libstub/arm-stub.c | 49 +
 1 file changed, 37 insertions(+), 12 deletions(-)

-- 
2.1.4



[PATCH v2 1/2] arm64/efi: report unexpected errors when determining Secure Boot status

2016-02-25 Thread Linn Crosetto
Certain code in the boot path may require the ability to determine whether
UEFI Secure Boot is definitely enabled, for example printing status to the
console. Other code may need to know when UEFI Secure Boot is definitely
disabled, for example restricting use of kernel parameters.

If an unexpected error is returned from GetVariable when querying the
status of UEFI Secure Boot, return an error to the caller. This allows the
caller to determine the definite state, and to take appropriate action if
an expected error is returned.

Signed-off-by: Linn Crosetto 
---
New patch in v2 based on feedback from v1:

 - Maintain existing behavior to allow 'dtb=' parameter only when UEFI
   Secure Boot is disabled and not in an unknown state. (Mark Rutland)

 drivers/firmware/efi/libstub/arm-stub.c | 17 -
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..b1bb133 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -18,7 +18,7 @@
 
 #include "efistub.h"
 
-static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
+static int efi_get_secureboot(efi_system_table_t *sys_table_arg)
 {
static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
static efi_char16_t const var_name[] = {
@@ -37,8 +37,12 @@ static int efi_secureboot_enabled(efi_system_table_t 
*sys_table_arg)
return val;
case EFI_NOT_FOUND:
return 0;
+   case EFI_DEVICE_ERROR:
+   return -EIO;
+   case EFI_SECURITY_VIOLATION:
+   return -EACCES;
default:
-   return 1;
+   return -EINVAL;
}
 }
 
@@ -183,6 +187,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0;
unsigned long reserve_size = 0;
+   int secure_boot = 0;
 
/* Check if we were booted by the EFI firmware */
if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
@@ -231,13 +236,15 @@ unsigned long efi_entry(void *handle, efi_system_table_t 
*sys_table,
if (status != EFI_SUCCESS)
pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 
+   secure_boot = efi_get_secureboot(sys_table);
+   if (secure_boot > 0)
+   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
+
/*
 * Unauthenticated device tree data is a security hazard, so
 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 */
-   if (efi_secureboot_enabled(sys_table)) {
-   pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
-   } else {
+   if (secure_boot == 0) {
status = handle_cmdline_files(sys_table, image, cmdline_ptr,
  "dtb=",
  ~0UL, _addr, _size);
-- 
2.1.4



[PATCH] arm64/efi: check SetupMode when determining Secure Boot status

2016-02-23 Thread Linn Crosetto
According to the UEFI specification, the platform is operating in secure
boot mode if SetupMode is 0 and SecureBoot is 1, and cannot operate in
secure boot mode if SetupMode is set to 1. Check the value of SetupMode
when determining the state of Secure Boot.

Signed-off-by: Linn Crosetto <l...@hpe.com>
---
 drivers/firmware/efi/libstub/arm-stub.c | 34 +
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..7ef2e20 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,26 +20,36 @@
 
 static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
-   switch (status) {
-   case EFI_SUCCESS:
-   return val;
-   case EFI_NOT_FOUND:
+   if (status != EFI_SUCCESS)
return 0;
-   default:
-   return 1;
-   }
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   return 0;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
 }
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
-- 
2.1.4



[PATCH] arm64/efi: check SetupMode when determining Secure Boot status

2016-02-23 Thread Linn Crosetto
According to the UEFI specification, the platform is operating in secure
boot mode if SetupMode is 0 and SecureBoot is 1, and cannot operate in
secure boot mode if SetupMode is set to 1. Check the value of SetupMode
when determining the state of Secure Boot.

Signed-off-by: Linn Crosetto 
---
 drivers/firmware/efi/libstub/arm-stub.c | 34 +
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
index 3397902..7ef2e20 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -20,26 +20,36 @@
 
 static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
 {
-   static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
-   static efi_char16_t const var_name[] = {
+   static efi_char16_t const sb_var_name[] = {
'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
+   static efi_char16_t const sm_var_name[] = {
+   'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 };
 
+   efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
-   unsigned long size = sizeof(u8);
-   efi_status_t status;
u8 val;
+   unsigned long size = sizeof(val);
+   efi_status_t status;
 
-   status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)_guid,
+   status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)_guid,
  NULL, , );
 
-   switch (status) {
-   case EFI_SUCCESS:
-   return val;
-   case EFI_NOT_FOUND:
+   if (status != EFI_SUCCESS)
return 0;
-   default:
-   return 1;
-   }
+
+   if (val == 0)
+   return 0;
+
+   status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)_guid,
+ NULL, , );
+
+   if (status != EFI_SUCCESS)
+   return 0;
+
+   if (val == 1)
+   return 0;
+
+   return 1;
 }
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
-- 
2.1.4



Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-26 Thread Linn Crosetto
On Wed, Mar 26, 2014 at 10:04:52AM -0700, Yinghai Lu wrote:
> On Wed, Mar 26, 2014 at 9:50 AM, Linn Crosetto  wrote:
> > On Tue, Mar 25, 2014 at 05:18:53PM -0700, Yinghai Lu wrote:
> >
> > Just noting that not all bits above first_system_vector are set in the 
> > bitmap,
> > so the comment in asm/desc.h and the change log could be misleading:
> >
> > /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
> >
> 
> Do you mean some vector that is neither used by percpu_vector_irq nor
> system_vector
> after first_system_vector ?

Yes, that is the case. In my previous example, first_system_vector is 239, but
test_bit(240, used_vectors) would return unset, though it cannot be used by
percpu vector_irq. If it marked all vectors unusable by percpu vector_irq, then
all bits above first_system_vector would be set.

> Anyway if bit is set in used_vectors, that vector can not be used by
> percpu vector_irq.
> 
> so that statement looks still right.
> 
> Feel free to suggest right comment or changelog.

The following might be more accurate:

/* 
 * The used_vectors BITMAP marks IRQs not managed by percpu vector_irq, below
 * first_system_vector. Vectors above first_system_vector are not managed by
 * percpu vector_irq.
 */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-26 Thread Linn Crosetto
On Tue, Mar 25, 2014 at 05:18:53PM -0700, Yinghai Lu wrote:
> On Tue, Mar 25, 2014 at 1:03 PM, Linn Crosetto  wrote:
> > Thanks for the patch.
> >
> > On Tue, Jan 28, 2014 at 01:54:05PM -0800, Yinghai Lu wrote:
> >> used_vectors is a bitmap for vectors that are not tracked in per_cpu
> >> vector_irq.
> >
> > I feel like this comment (also in the code) could be misleading because 
> > vectors
> > above first_system_vector are effectively not tracked in per_cpu 
> > vector_irq, but
> > also may not have the bit set in used_vectors. For example, used_vectors 
> > from a
> > system that I am looking at now:
> >
> > first_system_vector
> > 239  255
> >   |  |
> >   10 01000 1 1
> >
> > test_bit(240, used_vectors) does not return the correct answer to the 
> > question
> > about whether the vector is tracked in per_cpu vector_irq. This leads to two
> > meanings for the bitmap; for vectors less than first_system_vector whether 
> > or
> > not they are tracked in per_cpu vector_irq, and for vectors above
> > first_system_vector, whether or not they are in use:
> >
> > static inline int is_per_cpu_vector(int vector) {
> > return !test_bit(vector, used_vectors) &&
> > vector < first_system_vector;
> > }
> 
> sorry, I can not catch what you want to say.
> 
> Do you mean the change log or comment in the patch is not right?

Just noting that not all bits above first_system_vector are set in the bitmap,
so the comment in asm/desc.h and the change log could be misleading:

/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */

I have tested and the patch itself is good.

Thanks,
Linn
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-26 Thread Linn Crosetto
On Tue, Mar 25, 2014 at 05:18:53PM -0700, Yinghai Lu wrote:
 On Tue, Mar 25, 2014 at 1:03 PM, Linn Crosetto l...@hp.com wrote:
  Thanks for the patch.
 
  On Tue, Jan 28, 2014 at 01:54:05PM -0800, Yinghai Lu wrote:
  used_vectors is a bitmap for vectors that are not tracked in per_cpu
  vector_irq.
 
  I feel like this comment (also in the code) could be misleading because 
  vectors
  above first_system_vector are effectively not tracked in per_cpu 
  vector_irq, but
  also may not have the bit set in used_vectors. For example, used_vectors 
  from a
  system that I am looking at now:
 
  first_system_vector
  239  255
|  |
10 01000 1 1
 
  test_bit(240, used_vectors) does not return the correct answer to the 
  question
  about whether the vector is tracked in per_cpu vector_irq. This leads to two
  meanings for the bitmap; for vectors less than first_system_vector whether 
  or
  not they are tracked in per_cpu vector_irq, and for vectors above
  first_system_vector, whether or not they are in use:
 
  static inline int is_per_cpu_vector(int vector) {
  return !test_bit(vector, used_vectors) 
  vector  first_system_vector;
  }
 
 sorry, I can not catch what you want to say.
 
 Do you mean the change log or comment in the patch is not right?

Just noting that not all bits above first_system_vector are set in the bitmap,
so the comment in asm/desc.h and the change log could be misleading:

/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */

I have tested and the patch itself is good.

Thanks,
Linn
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-26 Thread Linn Crosetto
On Wed, Mar 26, 2014 at 10:04:52AM -0700, Yinghai Lu wrote:
 On Wed, Mar 26, 2014 at 9:50 AM, Linn Crosetto l...@hp.com wrote:
  On Tue, Mar 25, 2014 at 05:18:53PM -0700, Yinghai Lu wrote:
 
  Just noting that not all bits above first_system_vector are set in the 
  bitmap,
  so the comment in asm/desc.h and the change log could be misleading:
 
  /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
 
 
 Do you mean some vector that is neither used by percpu_vector_irq nor
 system_vector
 after first_system_vector ?

Yes, that is the case. In my previous example, first_system_vector is 239, but
test_bit(240, used_vectors) would return unset, though it cannot be used by
percpu vector_irq. If it marked all vectors unusable by percpu vector_irq, then
all bits above first_system_vector would be set.

 Anyway if bit is set in used_vectors, that vector can not be used by
 percpu vector_irq.
 
 so that statement looks still right.
 
 Feel free to suggest right comment or changelog.

The following might be more accurate:

/* 
 * The used_vectors BITMAP marks IRQs not managed by percpu vector_irq, below
 * first_system_vector. Vectors above first_system_vector are not managed by
 * percpu vector_irq.
 */
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-25 Thread Linn Crosetto
Thanks for the patch.

On Tue, Jan 28, 2014 at 01:54:05PM -0800, Yinghai Lu wrote:
> used_vectors is a bitmap for vectors that are not tracked in per_cpu
> vector_irq.

I feel like this comment (also in the code) could be misleading because vectors
above first_system_vector are effectively not tracked in per_cpu vector_irq, but
also may not have the bit set in used_vectors. For example, used_vectors from a
system that I am looking at now:

first_system_vector
239  255
  |  |
  10 01000 1 1

test_bit(240, used_vectors) does not return the correct answer to the question
about whether the vector is tracked in per_cpu vector_irq. This leads to two
meanings for the bitmap; for vectors less than first_system_vector whether or
not they are tracked in per_cpu vector_irq, and for vectors above
first_system_vector, whether or not they are in use:

static inline int is_per_cpu_vector(int vector) {
return !test_bit(vector, used_vectors) &&
vector < first_system_vector;
}

Thanks,
Linn

> used_vectors contains information on the first 32 exceptions, the system 
> vectors.
> the IA32_SYSCALL_VECTOR (0x80), and the IRQ_MOVE_CLEANUP_VECTOR (0x20).
> 
> assign_irq_vectors() assigns vectors up to first_system_vector and
> it will not use vectors that are set used_vectors.
> 
> This patch modifies the code to scan up to first_system_vector
> and do a test on the used_vectors bitmap.
> 
> So count avaiable vectors correctly.
> 
> -v2: fix compiling problem.
> -v3: update changelog and commets
> 
> Signed-off-by: Yinghai Lu 
> 
> ---
>  arch/x86/kernel/irq.c |   18 --
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> Index: linux-2.6/arch/x86/kernel/irq.c
> ===
> --- linux-2.6.orig/arch/x86/kernel/irq.c
> +++ linux-2.6/arch/x86/kernel/irq.c
> @@ -17,6 +17,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define CREATE_TRACE_POINTS
>  #include 
> @@ -321,8 +322,21 @@ int check_irq_vectors_for_cpu_disable(vo
>   for_each_online_cpu(cpu) {
>   if (cpu == this_cpu)
>   continue;
> - for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS;
> -  vector++) {
> +
> + /*
> +  * assign_irq_vector() only scan per_cpu vectors from
> +  * FIRST_EXTERNAL_VECTOR to first_system_vector.
> +  * It aslo skip vectors that are set in used_vectors bitmask.
> +  * used_vectors could have bits set for
> +  *  IA32_SYSCALL_VECTOR (0x80)
> +  *  IRQ_MOVE_CLEANUP_VECTOR (0x20)
> +  * Don't count those as available vectors.
> +  */
> + for (vector = FIRST_EXTERNAL_VECTOR;
> +  vector < first_system_vector; vector++) {
> + if (test_bit(vector, used_vectors))
> + continue;
> +
>   if (per_cpu(vector_irq, cpu)[vector] < 0)
>   count++;
>   }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] x86, irq: get correct available vectors for cpu disable

2014-03-25 Thread Linn Crosetto
Thanks for the patch.

On Tue, Jan 28, 2014 at 01:54:05PM -0800, Yinghai Lu wrote:
 used_vectors is a bitmap for vectors that are not tracked in per_cpu
 vector_irq.

I feel like this comment (also in the code) could be misleading because vectors
above first_system_vector are effectively not tracked in per_cpu vector_irq, but
also may not have the bit set in used_vectors. For example, used_vectors from a
system that I am looking at now:

first_system_vector
239  255
  |  |
  10 01000 1 1

test_bit(240, used_vectors) does not return the correct answer to the question
about whether the vector is tracked in per_cpu vector_irq. This leads to two
meanings for the bitmap; for vectors less than first_system_vector whether or
not they are tracked in per_cpu vector_irq, and for vectors above
first_system_vector, whether or not they are in use:

static inline int is_per_cpu_vector(int vector) {
return !test_bit(vector, used_vectors) 
vector  first_system_vector;
}

Thanks,
Linn

 used_vectors contains information on the first 32 exceptions, the system 
 vectors.
 the IA32_SYSCALL_VECTOR (0x80), and the IRQ_MOVE_CLEANUP_VECTOR (0x20).
 
 assign_irq_vectors() assigns vectors up to first_system_vector and
 it will not use vectors that are set used_vectors.
 
 This patch modifies the code to scan up to first_system_vector
 and do a test on the used_vectors bitmap.
 
 So count avaiable vectors correctly.
 
 -v2: fix compiling problem.
 -v3: update changelog and commets
 
 Signed-off-by: Yinghai Lu ying...@kernel.org
 
 ---
  arch/x86/kernel/irq.c |   18 --
  1 file changed, 16 insertions(+), 2 deletions(-)
 
 Index: linux-2.6/arch/x86/kernel/irq.c
 ===
 --- linux-2.6.orig/arch/x86/kernel/irq.c
 +++ linux-2.6/arch/x86/kernel/irq.c
 @@ -17,6 +17,7 @@
  #include asm/idle.h
  #include asm/mce.h
  #include asm/hw_irq.h
 +#include asm/desc.h
  
  #define CREATE_TRACE_POINTS
  #include asm/trace/irq_vectors.h
 @@ -321,8 +322,21 @@ int check_irq_vectors_for_cpu_disable(vo
   for_each_online_cpu(cpu) {
   if (cpu == this_cpu)
   continue;
 - for (vector = FIRST_EXTERNAL_VECTOR; vector  NR_VECTORS;
 -  vector++) {
 +
 + /*
 +  * assign_irq_vector() only scan per_cpu vectors from
 +  * FIRST_EXTERNAL_VECTOR to first_system_vector.
 +  * It aslo skip vectors that are set in used_vectors bitmask.
 +  * used_vectors could have bits set for
 +  *  IA32_SYSCALL_VECTOR (0x80)
 +  *  IRQ_MOVE_CLEANUP_VECTOR (0x20)
 +  * Don't count those as available vectors.
 +  */
 + for (vector = FIRST_EXTERNAL_VECTOR;
 +  vector  first_system_vector; vector++) {
 + if (test_bit(vector, used_vectors))
 + continue;
 +
   if (per_cpu(vector_irq, cpu)[vector]  0)
   count++;
   }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump

2014-03-14 Thread Linn Crosetto
On Fri, Mar 14, 2014 at 08:26:15AM +, Matt Fleming wrote:
> On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
> > 
> > Can you test with matt's tree to see if it works?
> > If it still happens please post the full log.
> 
> So that'd be the 'next' branch at,
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
> 
> which contains Borislav's fixes for the EFI memmap code.

I believe I included those fixes when testing with 3.14 rc6, adding:

https://lkml.org/lkml/2014/3/8/209
92b71d8
52d201e
a52f515
b660133
e91925d

Since this testing was done on a prototype, I will send you the log in a
separate email. I tried efi.git/next (with the addition of 4ce7a86), and hit the
same panic.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump

2014-03-14 Thread Linn Crosetto
On Fri, Mar 14, 2014 at 08:26:15AM +, Matt Fleming wrote:
 On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
  
  Can you test with matt's tree to see if it works?
  If it still happens please post the full log.
 
 So that'd be the 'next' branch at,
 
   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 
 which contains Borislav's fixes for the EFI memmap code.

I believe I included those fixes when testing with 3.14 rc6, adding:

https://lkml.org/lkml/2014/3/8/209
92b71d8
52d201e
a52f515
b660133
e91925d

Since this testing was done on a prototype, I will send you the log in a
separate email. I tried efi.git/next (with the addition of 4ce7a86), and hit the
same panic.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv3] x86: EFI stub support for large memory maps

2013-09-27 Thread Linn Crosetto
On Thu, Sep 26, 2013 at 12:34:00PM +0100, Matt Fleming wrote:
> > I might add the following to your merge for semantic reasons:
> > 
> > diff --git a/arch/x86/boot/compressed/eboot.c 
> > b/arch/x86/boot/compressed/eboot.c
> > index 04b228d..a7677ba 100644
> > --- a/arch/x86/boot/compressed/eboot.c
> > +++ b/arch/x86/boot/compressed/eboot.c
> > @@ -730,6 +730,8 @@ get_map:
> > boot_params->alt_mem_k = 32 * 1024;
> >  
> > status = setup_e820(boot_params, e820ext, e820ext_size);
> > +   if (status != EFI_SUCCESS)
> > +   return status;
> >  
> > return EFI_SUCCESS;
> 
> Aha, nice catch! Though if setup_e820() fails we should be jumping to
> the 'free_mem_map' label so we don't leak the memory map, like so,
> 
> diff --git a/arch/x86/boot/compressed/eboot.c 
> b/arch/x86/boot/compressed/eboot.c
> index 04b228d..602950b 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -730,8 +730,8 @@ get_map:
>   boot_params->alt_mem_k = 32 * 1024;
>  
>   status = setup_e820(boot_params, e820ext, e820ext_size);
> -
> - return EFI_SUCCESS;
> + if (status == EFI_SUCCESS)
> + return status;
>  
>  free_mem_map:
>   efi_call_phys1(sys_table->boottime->free_pool, mem_map);

Given that we have already successfully called exit_boot_services, can we still
make this call to free_pool?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv3] x86: EFI stub support for large memory maps

2013-09-27 Thread Linn Crosetto
On Thu, Sep 26, 2013 at 12:34:00PM +0100, Matt Fleming wrote:
  I might add the following to your merge for semantic reasons:
  
  diff --git a/arch/x86/boot/compressed/eboot.c 
  b/arch/x86/boot/compressed/eboot.c
  index 04b228d..a7677ba 100644
  --- a/arch/x86/boot/compressed/eboot.c
  +++ b/arch/x86/boot/compressed/eboot.c
  @@ -730,6 +730,8 @@ get_map:
  boot_params-alt_mem_k = 32 * 1024;
   
  status = setup_e820(boot_params, e820ext, e820ext_size);
  +   if (status != EFI_SUCCESS)
  +   return status;
   
  return EFI_SUCCESS;
 
 Aha, nice catch! Though if setup_e820() fails we should be jumping to
 the 'free_mem_map' label so we don't leak the memory map, like so,
 
 diff --git a/arch/x86/boot/compressed/eboot.c 
 b/arch/x86/boot/compressed/eboot.c
 index 04b228d..602950b 100644
 --- a/arch/x86/boot/compressed/eboot.c
 +++ b/arch/x86/boot/compressed/eboot.c
 @@ -730,8 +730,8 @@ get_map:
   boot_params-alt_mem_k = 32 * 1024;
  
   status = setup_e820(boot_params, e820ext, e820ext_size);
 -
 - return EFI_SUCCESS;
 + if (status == EFI_SUCCESS)
 + return status;
  
  free_mem_map:
   efi_call_phys1(sys_table-boottime-free_pool, mem_map);

Given that we have already successfully called exit_boot_services, can we still
make this call to free_pool?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv3] x86: EFI stub support for large memory maps

2013-09-25 Thread Linn Crosetto
On Wed, Sep 25, 2013 at 01:58:40PM +0100, Matt Fleming wrote:
> On Sun, 22 Sep, at 07:59:08PM, Linn Crosetto wrote:
> > This patch fixes a problem with EFI memory maps larger than 128 entries
> > when booting using the EFI stub, which results in overflowing e820_map
> > in boot_params and an eventual halt when checking the map size in
> > sanitize_e820_map().
> > 
> > If the number of map entries is greater than what can fit in e820_map,
> > add the extra entries to the setup_data list using type SETUP_E820_EXT.
> > These extra entries are then picked up when the setup_data list is
> > parsed in parse_e820_ext().
> > 
> > Signed-off-by: Linn Crosetto 
> > ---
> > Changes from v2:
> >  * Removed unnecessary optimization in alloc_e820ext() (Matt Fleming)
> >  * Fixed a bug where an incorrect buffer size may be passed to
> >get_memory_map when jumping to get_map
> > 
> >  arch/x86/boot/compressed/eboot.c | 239 
> > +++
> >  1 file changed, 167 insertions(+), 72 deletions(-)
> 
> Thanks Linn. I applied this to the 'next' branch at,
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
> 
> but it required a bit of massaging to apply on top of the changes
> already there. Could you confirm that my changes are OK? I've included
> the modified commit below.

I have tested the 'next' branch on a system with a large number of entries in
the memory map and the merge appears to be functionally correct. 

With the change in commit ae8e9060, I noticed the memory map is no longer placed
in memory allocated with low_alloc(). I have not looked into what effect it
could have, if any.

> + /* Historic? */
> + boot_params->alt_mem_k = 32 * 1024;
> +
> + status = setup_e820(boot_params, e820ext, e820ext_size);
>  
>   return EFI_SUCCESS;

I might add the following to your merge for semantic reasons:

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 04b228d..a7677ba 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -730,6 +730,8 @@ get_map:
boot_params->alt_mem_k = 32 * 1024;
 
status = setup_e820(boot_params, e820ext, e820ext_size);
+   if (status != EFI_SUCCESS)
+   return status;
 
return EFI_SUCCESS;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv3] x86: EFI stub support for large memory maps

2013-09-25 Thread Linn Crosetto
On Wed, Sep 25, 2013 at 01:58:40PM +0100, Matt Fleming wrote:
 On Sun, 22 Sep, at 07:59:08PM, Linn Crosetto wrote:
  This patch fixes a problem with EFI memory maps larger than 128 entries
  when booting using the EFI stub, which results in overflowing e820_map
  in boot_params and an eventual halt when checking the map size in
  sanitize_e820_map().
  
  If the number of map entries is greater than what can fit in e820_map,
  add the extra entries to the setup_data list using type SETUP_E820_EXT.
  These extra entries are then picked up when the setup_data list is
  parsed in parse_e820_ext().
  
  Signed-off-by: Linn Crosetto l...@hp.com
  ---
  Changes from v2:
   * Removed unnecessary optimization in alloc_e820ext() (Matt Fleming)
   * Fixed a bug where an incorrect buffer size may be passed to
 get_memory_map when jumping to get_map
  
   arch/x86/boot/compressed/eboot.c | 239 
  +++
   1 file changed, 167 insertions(+), 72 deletions(-)
 
 Thanks Linn. I applied this to the 'next' branch at,
 
   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 
 but it required a bit of massaging to apply on top of the changes
 already there. Could you confirm that my changes are OK? I've included
 the modified commit below.

I have tested the 'next' branch on a system with a large number of entries in
the memory map and the merge appears to be functionally correct. 

With the change in commit ae8e9060, I noticed the memory map is no longer placed
in memory allocated with low_alloc(). I have not looked into what effect it
could have, if any.

 + /* Historic? */
 + boot_params-alt_mem_k = 32 * 1024;
 +
 + status = setup_e820(boot_params, e820ext, e820ext_size);
  
   return EFI_SUCCESS;

I might add the following to your merge for semantic reasons:

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 04b228d..a7677ba 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -730,6 +730,8 @@ get_map:
boot_params-alt_mem_k = 32 * 1024;
 
status = setup_e820(boot_params, e820ext, e820ext_size);
+   if (status != EFI_SUCCESS)
+   return status;
 
return EFI_SUCCESS;


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv3] x86: EFI stub support for large memory maps

2013-09-22 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto 
---
Changes from v2:
 * Removed unnecessary optimization in alloc_e820ext() (Matt Fleming)
 * Fixed a bug where an incorrect buffer size may be passed to
   get_memory_map when jumping to get_map

 arch/x86/boot/compressed/eboot.c | 239 +++
 1 file changed, 167 insertions(+), 72 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..bfa177a 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,46 +982,198 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext->type = SETUP_E820_EXT;
+   e820ext->len = nr_entries * sizeof(struct e820entry);
+   e820ext->next = 0;
+
+   data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+   while (data && data->next)
+   data = (struct setup_data *)(unsigned long)data->next;
+
+   if (data)
+   data->next = (unsigned long)e820ext;
+   else
+   params->hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = >e820_map[0];
+   struct efi_info *efi = >efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
+
+   for (i = 0; i < nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi->efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
+   switch (d->type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev && prev->type == e820_type &&
+   (prev->addr + prev->size) == d->phys_addr) {
+   prev->size += d->num_pages << 12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params->e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size < need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext->data;
+   }
+
+   e820_map->addr = d->phys_addr;
+   e820_map->size = d->num_pages << PAGE_SHIFT;
+   e820_map->type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries > ARRAY_SIZE(params->e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params->e82

Re: [PATCHv2] x86: EFI stub support for large memory maps

2013-09-22 Thread Linn Crosetto
On Tue, Sep 17, 2013 at 09:14:52PM +0100, Matt Fleming wrote:
> > +static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
> > + u32 *e820ext_size)
> > +{
> > +   efi_status_t status;
> > +   unsigned long size;
> > +
> > +   size = sizeof(struct setup_data) +
> > +   sizeof(struct e820entry) * nr_desc;
> > +
> > +   if (*e820ext && size <= *e820ext_size)
> > +   return EFI_SUCCESS; /* Already allocated */
> 
> Do we actually need this check? I thought the 'prev_nr_desc' below
> ensures we only allocate 'e820ext' if we need more memory.

I am okay with removing the check. There is another bug in exit_boot, when
jumping to get_map the call to get the memory map is passed the previous map
size instead of the size of the allocated buffer. I'll make the changes and
resend.

> 
> [...]
> 
> > @@ -1016,6 +1157,19 @@ get_map:
> > if (status != EFI_SUCCESS)
> > goto free_mem_map;
> >  
> > +   prev_nr_desc = nr_desc;
> > +   nr_desc = size / desc_size;
> > +   if (nr_desc > prev_nr_desc &&
> > +   nr_desc > ARRAY_SIZE(boot_params->e820_map)) {
> > +   u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map);
> > +
> > +   status = alloc_e820ext(nr_e820ext, , _size);
> > +   if (status != EFI_SUCCESS)
> > +   goto free_mem_map;
> > +
> > +   goto get_map; /* Allocated memory, get map again */
> > +   }
> > +
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv2] x86: EFI stub support for large memory maps

2013-09-22 Thread Linn Crosetto
On Tue, Sep 17, 2013 at 09:14:52PM +0100, Matt Fleming wrote:
  +static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
  + u32 *e820ext_size)
  +{
  +   efi_status_t status;
  +   unsigned long size;
  +
  +   size = sizeof(struct setup_data) +
  +   sizeof(struct e820entry) * nr_desc;
  +
  +   if (*e820ext  size = *e820ext_size)
  +   return EFI_SUCCESS; /* Already allocated */
 
 Do we actually need this check? I thought the 'prev_nr_desc' below
 ensures we only allocate 'e820ext' if we need more memory.

I am okay with removing the check. There is another bug in exit_boot, when
jumping to get_map the call to get the memory map is passed the previous map
size instead of the size of the allocated buffer. I'll make the changes and
resend.

 
 [...]
 
  @@ -1016,6 +1157,19 @@ get_map:
  if (status != EFI_SUCCESS)
  goto free_mem_map;
   
  +   prev_nr_desc = nr_desc;
  +   nr_desc = size / desc_size;
  +   if (nr_desc  prev_nr_desc 
  +   nr_desc  ARRAY_SIZE(boot_params-e820_map)) {
  +   u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params-e820_map);
  +
  +   status = alloc_e820ext(nr_e820ext, e820ext, e820ext_size);
  +   if (status != EFI_SUCCESS)
  +   goto free_mem_map;
  +
  +   goto get_map; /* Allocated memory, get map again */
  +   }
  +
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv3] x86: EFI stub support for large memory maps

2013-09-22 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto l...@hp.com
---
Changes from v2:
 * Removed unnecessary optimization in alloc_e820ext() (Matt Fleming)
 * Fixed a bug where an incorrect buffer size may be passed to
   get_memory_map when jumping to get_map

 arch/x86/boot/compressed/eboot.c | 239 +++
 1 file changed, 167 insertions(+), 72 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..bfa177a 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,46 +982,198 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext-type = SETUP_E820_EXT;
+   e820ext-len = nr_entries * sizeof(struct e820entry);
+   e820ext-next = 0;
+
+   data = (struct setup_data *)(unsigned long)params-hdr.setup_data;
+
+   while (data  data-next)
+   data = (struct setup_data *)(unsigned long)data-next;
+
+   if (data)
+   data-next = (unsigned long)e820ext;
+   else
+   params-hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = params-e820_map[0];
+   struct efi_info *efi = params-efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi-efi_memmap_size / efi-efi_memdesc_size;
+
+   for (i = 0; i  nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi-efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi-efi_memdesc_size));
+   switch (d-type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev  prev-type == e820_type 
+   (prev-addr + prev-size) == d-phys_addr) {
+   prev-size += d-num_pages  12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params-e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size  need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext-data;
+   }
+
+   e820_map-addr = d-phys_addr;
+   e820_map-size = d-num_pages  PAGE_SHIFT;
+   e820_map-type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries  ARRAY_SIZE(params-e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params-e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params-e820_entries = (u8)nr_entries;
+
+   return EFI_SUCCESS;
+}
+
+static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
+ u32

[PATCH 2/3] x86: fix sparse warning in parse_e820_ext()

2013-09-06 Thread Linn Crosetto
Replace the call to early_iounmap() with early_memunmap() to eliminate
the following sparse warning:

arch/x86/kernel/e820.c:672:23: sparse: incorrect type in argument 1 (different 
address spaces)

Signed-off-by: Linn Crosetto 
---
 arch/x86/kernel/e820.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 174da5f..06e0c4a 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -669,7 +669,7 @@ void __init parse_e820_ext(u64 phys_addr, u32 data_len)
extmap = (struct e820entry *)(sdata->data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), _map);
-   early_iounmap(sdata, data_len);
+   early_memunmap(sdata, data_len);
printk(KERN_INFO "e820: extended physical RAM map:\n");
e820_print_map("extended");
 }
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] x86: fix early_iounmap() sparse warnings in setup.c

2013-09-06 Thread Linn Crosetto
Replace calls to early_iounmap() with early_memunmap() for pointers
mapped with early_memremap() to eliminate the following sparse warnings:

arch/x86/kernel/setup.c:355:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:441:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:470:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:491:31: warning: incorrect type in argument 1 
(different address spaces)

Signed-off-by: Linn Crosetto 
---
 arch/x86/kernel/setup.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f0de629..3081fc6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -352,7 +352,7 @@ static void __init relocate_initrd(void)
mapaddr = ramdisk_image & PAGE_MASK;
p = early_memremap(mapaddr, clen+slop);
memcpy(q, p+slop, clen);
-   early_iounmap(p, clen+slop);
+   early_memunmap(p, clen+slop);
q += clen;
ramdisk_image += clen;
ramdisk_size  -= clen;
@@ -438,7 +438,7 @@ static void __init parse_setup_data(void)
data_len = data->len + sizeof(struct setup_data);
data_type = data->type;
pa_next = data->next;
-   early_iounmap(data, map_len);
+   early_memunmap(data, map_len);
 
switch (data_type) {
case SETUP_E820_EXT:
@@ -467,7 +467,7 @@ static void __init e820_reserve_setup_data(void)
 E820_RAM, E820_RESERVED_KERN);
found = 1;
pa_data = data->next;
-   early_iounmap(data, sizeof(*data));
+   early_memunmap(data, sizeof(*data));
}
if (!found)
return;
@@ -488,7 +488,7 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
data = early_memremap(pa_data, sizeof(*data));
memblock_reserve(pa_data, sizeof(*data) + data->len);
pa_data = data->next;
-   early_iounmap(data, sizeof(*data));
+   early_memunmap(data, sizeof(*data));
}
 }
 
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] x86/mm: fix sparse warnings from early_memremap()

2013-09-06 Thread Linn Crosetto
This patch creates consistent early interfaces for mapping normal memory
and eliminates some sparse warnings.

early_memremap() was created to map normal memory, as opposed to the
ioremap interfaces for actual IO mappings, so remove the __iomem
annotation from early_memremap(). In addition, early_memunmap() is added
to provide an interface analogous to early_iounmap() for normal memory.

Fixes the following warnings:

arch/x86/kernel/setup.c:353:19: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:437:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:465:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:488:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/e820.c:667:15: warning: incorrect type in assignment (different 
address spaces)

Signed-off-by: Linn Crosetto 
---
 arch/x86/include/asm/io.h | 4 ++--
 arch/x86/mm/ioremap.c | 9 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 34f69cb..ae1ef3e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -325,8 +325,8 @@ extern void early_ioremap_init(void);
 extern void early_ioremap_reset(void);
 extern void __iomem *early_ioremap(resource_size_t phys_addr,
   unsigned long size);
-extern void __iomem *early_memremap(resource_size_t phys_addr,
-   unsigned long size);
+extern void *early_memremap(resource_size_t phys_addr, unsigned long size);
+extern void early_memunmap(void *addr, unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
 extern void fixup_early_ioremap(void);
 extern bool is_early_ioremap_ptep(pte_t *ptep);
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 799580c..a144929 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -562,10 +562,15 @@ early_ioremap(resource_size_t phys_addr, unsigned long 
size)
 }
 
 /* Remap memory */
-void __init __iomem *
+void __init *
 early_memremap(resource_size_t phys_addr, unsigned long size)
 {
-   return __early_ioremap(phys_addr, size, PAGE_KERNEL);
+   return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL);
+}
+
+void __init early_memunmap(void *addr, unsigned long size)
+{
+   early_iounmap((void __iomem *)addr, size);
 }
 
 void __init early_iounmap(void __iomem *addr, unsigned long size)
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/3] x86/mm: fix early_memremap() sparse warnings

2013-09-06 Thread Linn Crosetto
This set of patches cleans up some sparse warnings generated by callers of
early_memremap(). 

early_memremap() was created as an interface to to map normal memory (commit
1494177), in contrast to early_ioremap() for IO mappings. Later on,
early_memremap() was annotated with __iomem (commit 1d6cf1f) which generates
sparse warnings for callers using pointers not declared with __iomem. Callers
of early_memremap() were expected to use early_iounmap() to remove the mapping,
which generates more sparse warnings as the argument to early_iounmap() is also
annotated with __iomem.

To clean this up, remove __iomem from early_memremap() and create
early_memunmap() to be used for removing normal memory mappings.

Removes the following warnings:

arch/x86/kernel/setup.c:353:19: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:355:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:437:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:441:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:465:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:470:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:488:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:491:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/e820.c:667:15: warning: incorrect type in assignment (different 
address spaces)
arch/x86/kernel/e820.c:672:23: warning: incorrect type in argument 1 (different 
address spaces)

Linn Crosetto (3):
  x86/mm: fix sparse warnings from early_memremap()
  x86: fix sparse warning in parse_e820_ext()
  x86: fix early_iounmap() sparse warnings in setup.c

 arch/x86/include/asm/io.h | 4 ++--
 arch/x86/kernel/e820.c| 2 +-
 arch/x86/kernel/setup.c   | 8 
 arch/x86/mm/ioremap.c | 9 +++--
 4 files changed, 14 insertions(+), 9 deletions(-)

-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv2] x86: EFI stub support for large memory maps

2013-09-06 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto 
---
Changes in v2:
* Free memory when error is returned from alloc_e820ext() as suggested by Matt
  Fleming
* Set pointer to NULL and size to 0 after freeing memory in alloc_e820ext()

 arch/x86/boot/compressed/eboot.c | 223 ---
 1 file changed, 160 insertions(+), 63 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..2ac395e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,20 +982,161 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext->type = SETUP_E820_EXT;
+   e820ext->len = nr_entries * sizeof(struct e820entry);
+   e820ext->next = 0;
+
+   data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+   while (data && data->next)
+   data = (struct setup_data *)(unsigned long)data->next;
+
+   if (data)
+   data->next = (unsigned long)e820ext;
+   else
+   params->hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = >e820_map[0];
+   struct efi_info *efi = >efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
+
+   for (i = 0; i < nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi->efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
+   switch (d->type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev && prev->type == e820_type &&
+   (prev->addr + prev->size) == d->phys_addr) {
+   prev->size += d->num_pages << 12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params->e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size < need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext->data;
+   }
+
+   e820_map->addr = d->phys_addr;
+   e820_map->size = d->num_pages << PAGE_SHIFT;
+   e820_map->type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries > ARRAY_SIZE(params->e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params->e82

[PATCHv2] x86: EFI stub support for large memory maps

2013-09-06 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto l...@hp.com
---
Changes in v2:
* Free memory when error is returned from alloc_e820ext() as suggested by Matt
  Fleming
* Set pointer to NULL and size to 0 after freeing memory in alloc_e820ext()

 arch/x86/boot/compressed/eboot.c | 223 ---
 1 file changed, 160 insertions(+), 63 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..2ac395e 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,20 +982,161 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext-type = SETUP_E820_EXT;
+   e820ext-len = nr_entries * sizeof(struct e820entry);
+   e820ext-next = 0;
+
+   data = (struct setup_data *)(unsigned long)params-hdr.setup_data;
+
+   while (data  data-next)
+   data = (struct setup_data *)(unsigned long)data-next;
+
+   if (data)
+   data-next = (unsigned long)e820ext;
+   else
+   params-hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = params-e820_map[0];
+   struct efi_info *efi = params-efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi-efi_memmap_size / efi-efi_memdesc_size;
+
+   for (i = 0; i  nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi-efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi-efi_memdesc_size));
+   switch (d-type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev  prev-type == e820_type 
+   (prev-addr + prev-size) == d-phys_addr) {
+   prev-size += d-num_pages  12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params-e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size  need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext-data;
+   }
+
+   e820_map-addr = d-phys_addr;
+   e820_map-size = d-num_pages  PAGE_SHIFT;
+   e820_map-type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries  ARRAY_SIZE(params-e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params-e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params-e820_entries = (u8)nr_entries;
+
+   return EFI_SUCCESS;
+}
+
+static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
+ u32 *e820ext_size

[PATCH 0/3] x86/mm: fix early_memremap() sparse warnings

2013-09-06 Thread Linn Crosetto
This set of patches cleans up some sparse warnings generated by callers of
early_memremap(). 

early_memremap() was created as an interface to to map normal memory (commit
1494177), in contrast to early_ioremap() for IO mappings. Later on,
early_memremap() was annotated with __iomem (commit 1d6cf1f) which generates
sparse warnings for callers using pointers not declared with __iomem. Callers
of early_memremap() were expected to use early_iounmap() to remove the mapping,
which generates more sparse warnings as the argument to early_iounmap() is also
annotated with __iomem.

To clean this up, remove __iomem from early_memremap() and create
early_memunmap() to be used for removing normal memory mappings.

Removes the following warnings:

arch/x86/kernel/setup.c:353:19: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:355:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:437:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:441:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:465:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:470:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:488:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:491:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/e820.c:667:15: warning: incorrect type in assignment (different 
address spaces)
arch/x86/kernel/e820.c:672:23: warning: incorrect type in argument 1 (different 
address spaces)

Linn Crosetto (3):
  x86/mm: fix sparse warnings from early_memremap()
  x86: fix sparse warning in parse_e820_ext()
  x86: fix early_iounmap() sparse warnings in setup.c

 arch/x86/include/asm/io.h | 4 ++--
 arch/x86/kernel/e820.c| 2 +-
 arch/x86/kernel/setup.c   | 8 
 arch/x86/mm/ioremap.c | 9 +++--
 4 files changed, 14 insertions(+), 9 deletions(-)

-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] x86/mm: fix sparse warnings from early_memremap()

2013-09-06 Thread Linn Crosetto
This patch creates consistent early interfaces for mapping normal memory
and eliminates some sparse warnings.

early_memremap() was created to map normal memory, as opposed to the
ioremap interfaces for actual IO mappings, so remove the __iomem
annotation from early_memremap(). In addition, early_memunmap() is added
to provide an interface analogous to early_iounmap() for normal memory.

Fixes the following warnings:

arch/x86/kernel/setup.c:353:19: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:437:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:465:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/setup.c:488:22: warning: incorrect type in assignment 
(different address spaces)
arch/x86/kernel/e820.c:667:15: warning: incorrect type in assignment (different 
address spaces)

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/include/asm/io.h | 4 ++--
 arch/x86/mm/ioremap.c | 9 +++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index 34f69cb..ae1ef3e 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -325,8 +325,8 @@ extern void early_ioremap_init(void);
 extern void early_ioremap_reset(void);
 extern void __iomem *early_ioremap(resource_size_t phys_addr,
   unsigned long size);
-extern void __iomem *early_memremap(resource_size_t phys_addr,
-   unsigned long size);
+extern void *early_memremap(resource_size_t phys_addr, unsigned long size);
+extern void early_memunmap(void *addr, unsigned long size);
 extern void early_iounmap(void __iomem *addr, unsigned long size);
 extern void fixup_early_ioremap(void);
 extern bool is_early_ioremap_ptep(pte_t *ptep);
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 799580c..a144929 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -562,10 +562,15 @@ early_ioremap(resource_size_t phys_addr, unsigned long 
size)
 }
 
 /* Remap memory */
-void __init __iomem *
+void __init *
 early_memremap(resource_size_t phys_addr, unsigned long size)
 {
-   return __early_ioremap(phys_addr, size, PAGE_KERNEL);
+   return (__force void *)__early_ioremap(phys_addr, size, PAGE_KERNEL);
+}
+
+void __init early_memunmap(void *addr, unsigned long size)
+{
+   early_iounmap((void __iomem *)addr, size);
 }
 
 void __init early_iounmap(void __iomem *addr, unsigned long size)
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] x86: fix sparse warning in parse_e820_ext()

2013-09-06 Thread Linn Crosetto
Replace the call to early_iounmap() with early_memunmap() to eliminate
the following sparse warning:

arch/x86/kernel/e820.c:672:23: sparse: incorrect type in argument 1 (different 
address spaces)

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/kernel/e820.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 174da5f..06e0c4a 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -669,7 +669,7 @@ void __init parse_e820_ext(u64 phys_addr, u32 data_len)
extmap = (struct e820entry *)(sdata-data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), e820.nr_map);
-   early_iounmap(sdata, data_len);
+   early_memunmap(sdata, data_len);
printk(KERN_INFO e820: extended physical RAM map:\n);
e820_print_map(extended);
 }
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] x86: fix early_iounmap() sparse warnings in setup.c

2013-09-06 Thread Linn Crosetto
Replace calls to early_iounmap() with early_memunmap() for pointers
mapped with early_memremap() to eliminate the following sparse warnings:

arch/x86/kernel/setup.c:355:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:441:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:470:31: warning: incorrect type in argument 1 
(different address spaces)
arch/x86/kernel/setup.c:491:31: warning: incorrect type in argument 1 
(different address spaces)

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/kernel/setup.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f0de629..3081fc6 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -352,7 +352,7 @@ static void __init relocate_initrd(void)
mapaddr = ramdisk_image  PAGE_MASK;
p = early_memremap(mapaddr, clen+slop);
memcpy(q, p+slop, clen);
-   early_iounmap(p, clen+slop);
+   early_memunmap(p, clen+slop);
q += clen;
ramdisk_image += clen;
ramdisk_size  -= clen;
@@ -438,7 +438,7 @@ static void __init parse_setup_data(void)
data_len = data-len + sizeof(struct setup_data);
data_type = data-type;
pa_next = data-next;
-   early_iounmap(data, map_len);
+   early_memunmap(data, map_len);
 
switch (data_type) {
case SETUP_E820_EXT:
@@ -467,7 +467,7 @@ static void __init e820_reserve_setup_data(void)
 E820_RAM, E820_RESERVED_KERN);
found = 1;
pa_data = data-next;
-   early_iounmap(data, sizeof(*data));
+   early_memunmap(data, sizeof(*data));
}
if (!found)
return;
@@ -488,7 +488,7 @@ static void __init 
memblock_x86_reserve_range_setup_data(void)
data = early_memremap(pa_data, sizeof(*data));
memblock_reserve(pa_data, sizeof(*data) + data-len);
pa_data = data-next;
-   early_iounmap(data, sizeof(*data));
+   early_memunmap(data, sizeof(*data));
}
 }
 
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/mm] x86: avoid remapping data in parse_setup_data()

2013-09-01 Thread tip-bot for Linn Crosetto
Commit-ID:  30e46b574a1db7d14404e52dca8e1aa5f5155fd2
Gitweb: http://git.kernel.org/tip/30e46b574a1db7d14404e52dca8e1aa5f5155fd2
Author: Linn Crosetto 
AuthorDate: Tue, 13 Aug 2013 15:46:41 -0600
Committer:  H. Peter Anvin 
CommitDate: Tue, 13 Aug 2013 23:29:19 -0700

x86: avoid remapping data in parse_setup_data()

Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.

Signed-off-by: Linn Crosetto 
Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-l...@hp.com
Acked-by: Yinghai Lu 
Reviewed-by: Pekka Enberg 
Signed-off-by: H. Peter Anvin 
---
 arch/x86/include/asm/e820.h |  2 +-
 arch/x86/kernel/e820.c  |  5 -
 arch/x86/kernel/setup.c | 19 ---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index cccd07f..779c2ef 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data);
+extern void parse_e820_ext(u64 phys_addr, u32 data_len);
 
 #if defined(CONFIG_X86_64) || \
(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d32abea..174da5f 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata)
+void __init parse_e820_ext(u64 phys_addr, u32 data_len)
 {
int entries;
struct e820entry *extmap;
+   struct setup_data *sdata;
 
+   sdata = early_memremap(phys_addr, data_len);
entries = sdata->len / sizeof(struct e820entry);
extmap = (struct e820entry *)(sdata->data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), _map);
+   early_iounmap(sdata, data_len);
printk(KERN_INFO "e820: extended physical RAM map:\n");
e820_print_map("extended");
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index de33798..b6b45e4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void)
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
-   u64 pa_data;
+   u64 pa_data, pa_next;
 
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
-   u32 data_len, map_len;
+   u32 data_len, map_len, data_type;
 
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
-   if (data_len > map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
+   data_type = data->type;
+   pa_next = data->next;
+   early_iounmap(data, map_len);
 
-   switch (data->type) {
+   switch (data_type) {
case SETUP_E820_EXT:
-   parse_e820_ext(data);
+   parse_e820_ext(pa_data, data_len);
break;
case SETUP_DTB:
add_dtb(pa_data);
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void)
default:
break;
}
-   pa_data = data->next;
-   early_iounmap(data, map_len);
+   pa_data = pa_next;
}
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/mm] x86: avoid remapping data in parse_setup_data()

2013-09-01 Thread tip-bot for Linn Crosetto
Commit-ID:  30e46b574a1db7d14404e52dca8e1aa5f5155fd2
Gitweb: http://git.kernel.org/tip/30e46b574a1db7d14404e52dca8e1aa5f5155fd2
Author: Linn Crosetto l...@hp.com
AuthorDate: Tue, 13 Aug 2013 15:46:41 -0600
Committer:  H. Peter Anvin h...@linux.intel.com
CommitDate: Tue, 13 Aug 2013 23:29:19 -0700

x86: avoid remapping data in parse_setup_data()

Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.

Signed-off-by: Linn Crosetto l...@hp.com
Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-l...@hp.com
Acked-by: Yinghai Lu ying...@kernel.org
Reviewed-by: Pekka Enberg penb...@kernel.org
Signed-off-by: H. Peter Anvin h...@linux.intel.com
---
 arch/x86/include/asm/e820.h |  2 +-
 arch/x86/kernel/e820.c  |  5 -
 arch/x86/kernel/setup.c | 19 ---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index cccd07f..779c2ef 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data);
+extern void parse_e820_ext(u64 phys_addr, u32 data_len);
 
 #if defined(CONFIG_X86_64) || \
(defined(CONFIG_X86_32)  defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d32abea..174da5f 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata)
+void __init parse_e820_ext(u64 phys_addr, u32 data_len)
 {
int entries;
struct e820entry *extmap;
+   struct setup_data *sdata;
 
+   sdata = early_memremap(phys_addr, data_len);
entries = sdata-len / sizeof(struct e820entry);
extmap = (struct e820entry *)(sdata-data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), e820.nr_map);
+   early_iounmap(sdata, data_len);
printk(KERN_INFO e820: extended physical RAM map:\n);
e820_print_map(extended);
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index de33798..b6b45e4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void)
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
-   u64 pa_data;
+   u64 pa_data, pa_next;
 
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
-   u32 data_len, map_len;
+   u32 data_len, map_len, data_type;
 
map_len = max(PAGE_SIZE - (pa_data  ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data-len + sizeof(struct setup_data);
-   if (data_len  map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
+   data_type = data-type;
+   pa_next = data-next;
+   early_iounmap(data, map_len);
 
-   switch (data-type) {
+   switch (data_type) {
case SETUP_E820_EXT:
-   parse_e820_ext(data);
+   parse_e820_ext(pa_data, data_len);
break;
case SETUP_DTB:
add_dtb(pa_data);
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void)
default:
break;
}
-   pa_data = data-next;
-   early_iounmap(data, map_len);
+   pa_data = pa_next;
}
 }
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] x86: EFI stub support for large memory maps

2013-08-23 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto 
---
 arch/x86/boot/compressed/eboot.c | 220 ---
 1 file changed, 157 insertions(+), 63 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..89fcfe6 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,20 +982,158 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext->type = SETUP_E820_EXT;
+   e820ext->len = nr_entries * sizeof(struct e820entry);
+   e820ext->next = 0;
+
+   data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
+
+   while (data && data->next)
+   data = (struct setup_data *)(unsigned long)data->next;
+
+   if (data)
+   data->next = (unsigned long)e820ext;
+   else
+   params->hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = >e820_map[0];
+   struct efi_info *efi = >efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
+
+   for (i = 0; i < nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi->efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
+   switch (d->type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev && prev->type == e820_type &&
+   (prev->addr + prev->size) == d->phys_addr) {
+   prev->size += d->num_pages << 12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params->e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size < need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext->data;
+   }
+
+   e820_map->addr = d->phys_addr;
+   e820_map->size = d->num_pages << PAGE_SHIFT;
+   e820_map->type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries > ARRAY_SIZE(params->e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params->e820_entries = (u8)nr_entries;
+
+   return EFI_SUCCESS;
+}
+
+static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
+ u32 *e820ext_size)
+{
+   efi_st

[PATCH] x86: EFI stub support for large memory maps

2013-08-23 Thread Linn Crosetto
This patch fixes a problem with EFI memory maps larger than 128 entries
when booting using the EFI stub, which results in overflowing e820_map
in boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

If the number of map entries is greater than what can fit in e820_map,
add the extra entries to the setup_data list using type SETUP_E820_EXT.
These extra entries are then picked up when the setup_data list is
parsed in parse_e820_ext().

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/boot/compressed/eboot.c | 220 ---
 1 file changed, 157 insertions(+), 63 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..89fcfe6 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -982,20 +982,158 @@ fail:
return NULL;
 }
 
+static void add_e820ext(struct boot_params *params,
+   struct setup_data *e820ext, u32 nr_entries)
+{
+   struct setup_data *data;
+   efi_status_t status;
+   unsigned long size;
+
+   e820ext-type = SETUP_E820_EXT;
+   e820ext-len = nr_entries * sizeof(struct e820entry);
+   e820ext-next = 0;
+
+   data = (struct setup_data *)(unsigned long)params-hdr.setup_data;
+
+   while (data  data-next)
+   data = (struct setup_data *)(unsigned long)data-next;
+
+   if (data)
+   data-next = (unsigned long)e820ext;
+   else
+   params-hdr.setup_data = (unsigned long)e820ext;
+}
+
+static efi_status_t setup_e820(struct boot_params *params,
+  struct setup_data *e820ext, u32 e820ext_size)
+{
+   struct e820entry *e820_map = params-e820_map[0];
+   struct efi_info *efi = params-efi_info;
+   struct e820entry *prev = NULL;
+   u32 nr_entries;
+   u32 nr_desc;
+   int i;
+
+   nr_entries = 0;
+   nr_desc = efi-efi_memmap_size / efi-efi_memdesc_size;
+
+   for (i = 0; i  nr_desc; i++) {
+   efi_memory_desc_t *d;
+   unsigned int e820_type = 0;
+   unsigned long m = efi-efi_memmap;
+
+   d = (efi_memory_desc_t *)(m + (i * efi-efi_memdesc_size));
+   switch (d-type) {
+   case EFI_RESERVED_TYPE:
+   case EFI_RUNTIME_SERVICES_CODE:
+   case EFI_RUNTIME_SERVICES_DATA:
+   case EFI_MEMORY_MAPPED_IO:
+   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+   case EFI_PAL_CODE:
+   e820_type = E820_RESERVED;
+   break;
+
+   case EFI_UNUSABLE_MEMORY:
+   e820_type = E820_UNUSABLE;
+   break;
+
+   case EFI_ACPI_RECLAIM_MEMORY:
+   e820_type = E820_ACPI;
+   break;
+
+   case EFI_LOADER_CODE:
+   case EFI_LOADER_DATA:
+   case EFI_BOOT_SERVICES_CODE:
+   case EFI_BOOT_SERVICES_DATA:
+   case EFI_CONVENTIONAL_MEMORY:
+   e820_type = E820_RAM;
+   break;
+
+   case EFI_ACPI_MEMORY_NVS:
+   e820_type = E820_NVS;
+   break;
+
+   default:
+   continue;
+   }
+
+   /* Merge adjacent mappings */
+   if (prev  prev-type == e820_type 
+   (prev-addr + prev-size) == d-phys_addr) {
+   prev-size += d-num_pages  12;
+   continue;
+   }
+
+   if (nr_entries == ARRAY_SIZE(params-e820_map)) {
+   u32 need = (nr_desc - i) * sizeof(struct e820entry) +
+  sizeof(struct setup_data);
+
+   if (!e820ext || e820ext_size  need)
+   return EFI_BUFFER_TOO_SMALL;
+
+   /* boot_params map full, switch to e820 extended */
+   e820_map = (struct e820entry *)e820ext-data;
+   }
+
+   e820_map-addr = d-phys_addr;
+   e820_map-size = d-num_pages  PAGE_SHIFT;
+   e820_map-type = e820_type;
+   prev = e820_map++;
+   nr_entries++;
+   }
+
+   if (nr_entries  ARRAY_SIZE(params-e820_map)) {
+   u32 nr_e820ext = nr_entries - ARRAY_SIZE(params-e820_map);
+
+   add_e820ext(params, e820ext, nr_e820ext);
+   nr_entries -= nr_e820ext;
+   }
+
+   params-e820_entries = (u8)nr_entries;
+
+   return EFI_SUCCESS;
+}
+
+static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
+ u32 *e820ext_size)
+{
+   efi_status_t status;
+   unsigned long size;
+
+   size = sizeof(struct setup_data) +
+   sizeof(struct e820entry) * nr_desc;
+
+   if (*e820ext

Re: [RFC PATCH 0/4] EFI boot stub memory map fix

2013-08-19 Thread Linn Crosetto
On Mon, Aug 19, 2013 at 01:47:41PM -0700, Yinghai Lu wrote:
> On Mon, Aug 19, 2013 at 1:06 PM, H. Peter Anvin  wrote:
> > I would strongly disagree that option 2 is the cleaner solution.
> 
> Agreed.
> 
> >
> > Linn Crosetto  wrote:
> >>I realize the EFI stub for ARM patches are in flight,
> >>
> >>https://lkml.org/lkml/2013/8/9/554
> >>
> >>and overlap with some of the files but I wanted to send these out for
> >>comment.
> >>
> >>This series fixes a problem with EFI memory maps larger than 128
> >>entries when
> >>booting using the EFI boot stub, which results in overflowing the
> >>e820_map in
> >>boot_params and an eventual halt when checking the map size in
> >>sanitize_e820_map().
> >>
> >>The fix implemented is to add the EFI memory map from setup_arch() via
> >>a
> >>memory_setup hook.
> >>
> >>Two options were considered:
> >>
> >> 1. Use the SETUP_E820_EXT setup_data type to add the extra entries.
> >>
> >>2. Create a memory_setup function to be enabled when the EFI memory map
> >>is
> >>needed.
> >>
> >>Option 2 appeared to be the cleaner solution, reducing duplication with
> >>existing code, given a reasonable mechanism for determining when to
> >>replace the default memory_setup function.
> 
> If boot_loader could create setup_data with SETUP_E820_EXT,
> efi_stub should go that path too.
> We should not add another path.

My consideration was in leveraging do_add_efi_memmap(), which duplicates what is
done with the map in exit_boot(), and can already be called via the
"add_efi_memmap" parameter. One complication with SETUP_E820_EXT is in
determining the size needed, since a call to allocate_pool will change the
memory map. 

I will send another version which uses SETUP_E820_EXT.

Thanks,
Linn
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 3/4] efi: Add efi_memmap_needed()

2013-08-19 Thread Linn Crosetto
The function efi_memmap_needed() is used to determine when to use the
EFI memory map during boot instead of a BIOS provided e820.

The intent is to determine whether we are booted on an EFI system from
the EFI boot stub (came in through efi_main(), implemented by checking
efi_is_native() and the boot loader identifier), and that there is no
e820 map already provided.

Signed-off-by: Linn Crosetto 
---
 arch/x86/platform/efi/efi.c | 7 +++
 include/linux/efi.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index c2a660c..af32a21 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -719,6 +719,13 @@ char * __init efi_memory_setup(void)
return who;
 }
 
+int __init efi_memmap_needed(void)
+{
+   return efi_is_native() &&
+  boot_params.e820_entries == 0 &&
+  boot_params.hdr.type_of_loader >> 4 == 2; /* bootsect-loader */
+}
+
 void __init efi_init(void)
 {
efi_char16_t *c16;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 977bbc7..95b2251 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -567,6 +567,7 @@ efi_guid_unparse(efi_guid_t *guid, char *out)
 return out;
 }
 
+extern int efi_memmap_needed(void);
 extern char *efi_memory_setup(void);
 extern void efi_init (void);
 extern void *efi_get_pal_addr (void);
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 4/4] x86: Fix EFI boot stub for large memory maps

2013-08-19 Thread Linn Crosetto
This patch adds support for EFI memory maps larger than 128 entries when
booted using the EFI boot stub.

The e820 map in struct boot_params can only hold 128 entries, but the
memory map provided by EFI may be larger. If the map contained more than
128 entries, exit_boot() would write beyond the e820_map array in
boot_params and the system would eventually halt in the BUG_ON check in
sanitize_e820_map().

In the case we come in through efi_main(), the EFI memory map is used.
Instead of populating e820_map in boot_params, create the e820 from the
EFI memory map in setup_arch() via a memory_setup hook.

The EFI memory map may also be added in efi_init() if the command line
parameter "add_efi_memmap" is specified. This is left intact to allow
the command line parameter to remain effective.

Signed-off-by: Linn Crosetto 
---
 arch/x86/boot/compressed/eboot.c | 64 ++--
 arch/x86/kernel/setup.c  |  3 ++
 2 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..66b8d3d 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -973,6 +973,9 @@ struct boot_params *make_boot_params(void *handle, 
efi_system_table_t *_table)
if (status != EFI_SUCCESS)
goto fail2;
 
+   /* Use EFI memory map */
+   boot_params->e820_entries = 0;
+
return boot_params;
 fail2:
if (options_size)
@@ -986,8 +989,6 @@ static efi_status_t exit_boot(struct boot_params 
*boot_params,
  void *handle)
 {
struct efi_info *efi = _params->efi_info;
-   struct e820entry *e820_map = _params->e820_map[0];
-   struct e820entry *prev = NULL;
unsigned long size, key, desc_size, _size;
efi_memory_desc_t *mem_map;
efi_status_t status;
@@ -1049,65 +1050,6 @@ get_map:
/* Historic? */
boot_params->alt_mem_k = 32 * 1024;
 
-   /*
-* Convert the EFI memory map to E820.
-*/
-   nr_entries = 0;
-   for (i = 0; i < size / desc_size; i++) {
-   efi_memory_desc_t *d;
-   unsigned int e820_type = 0;
-   unsigned long m = (unsigned long)mem_map;
-
-   d = (efi_memory_desc_t *)(m + (i * desc_size));
-   switch (d->type) {
-   case EFI_RESERVED_TYPE:
-   case EFI_RUNTIME_SERVICES_CODE:
-   case EFI_RUNTIME_SERVICES_DATA:
-   case EFI_MEMORY_MAPPED_IO:
-   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
-   case EFI_PAL_CODE:
-   e820_type = E820_RESERVED;
-   break;
-
-   case EFI_UNUSABLE_MEMORY:
-   e820_type = E820_UNUSABLE;
-   break;
-
-   case EFI_ACPI_RECLAIM_MEMORY:
-   e820_type = E820_ACPI;
-   break;
-
-   case EFI_LOADER_CODE:
-   case EFI_LOADER_DATA:
-   case EFI_BOOT_SERVICES_CODE:
-   case EFI_BOOT_SERVICES_DATA:
-   case EFI_CONVENTIONAL_MEMORY:
-   e820_type = E820_RAM;
-   break;
-
-   case EFI_ACPI_MEMORY_NVS:
-   e820_type = E820_NVS;
-   break;
-
-   default:
-   continue;
-   }
-
-   /* Merge adjacent mappings */
-   if (prev && prev->type == e820_type &&
-   (prev->addr + prev->size) == d->phys_addr)
-   prev->size += d->num_pages << 12;
-   else {
-   e820_map->addr = d->phys_addr;
-   e820_map->size = d->num_pages << 12;
-   e820_map->type = e820_type;
-   prev = e820_map++;
-   nr_entries++;
-   }
-   }
-
-   boot_params->e820_entries = nr_entries;
-
return EFI_SUCCESS;
 
 free_mem_map:
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..9682c8c 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -920,6 +920,9 @@ void __init setup_arch(char **cmdline_p)
 
if (efi_enabled(EFI_BOOT))
efi_memblock_x86_reserve_range();
+
+   if (efi_memmap_needed())
+   x86_init.resources.memory_setup = efi_memory_setup;
 #endif
 
x86_init.oem.arch_setup();
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 0/4] EFI boot stub memory map fix

2013-08-19 Thread Linn Crosetto
I realize the EFI stub for ARM patches are in flight, 

https://lkml.org/lkml/2013/8/9/554

and overlap with some of the files but I wanted to send these out for comment.

This series fixes a problem with EFI memory maps larger than 128 entries when
booting using the EFI boot stub, which results in overflowing the e820_map in
boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

The fix implemented is to add the EFI memory map from setup_arch() via a
memory_setup hook.

Two options were considered:

 1. Use the SETUP_E820_EXT setup_data type to add the extra entries.

 2. Create a memory_setup function to be enabled when the EFI memory map is
needed.

Option 2 appeared to be the cleaner solution, reducing duplication with
existing code, given a reasonable mechanism for determining when to
replace the default memory_setup function.


Linn Crosetto (4):
  efi: Decouple efi_memmap_init() and do_add_efi_memmap()
  efi: Add memory_setup function efi_memory_setup()
  efi: Add efi_memmap_needed()
  x86: Fix EFI boot stub for large memory maps

 arch/x86/boot/compressed/eboot.c | 64 ++--
 arch/x86/kernel/setup.c  |  3 ++
 arch/x86/platform/efi/efi.c  | 51 +++-
 include/linux/efi.h  |  2 ++
 4 files changed, 45 insertions(+), 75 deletions(-)

-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 1/4] efi: Decouple efi_memmap_init() and do_add_efi_memmap()

2013-08-19 Thread Linn Crosetto
In order to enable the EFI memory map to be initialized outside of
efi_init(), decouple the two functions efi_memmap_init() and
do_add_efi_memmap() and set the x86_facility EFI_MEMMAP in
efi_memmap_init(). Additionally, check EFI_MEMMAP to determine whether
efi_memmap_init() has been previously called to avoid doing the
initialization more than once.

Signed-off-by: Linn Crosetto 
---
 arch/x86/platform/efi/efi.c | 44 ++--
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 90f6ed1..32da922 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -326,6 +326,24 @@ void efi_get_time(struct timespec *now)
now->tv_nsec = 0;
 }
 
+static int __init efi_memmap_init(void)
+{
+   if (efi_enabled(EFI_MEMMAP))
+   return 0; /* already initialized */
+
+   /* Map the EFI memory map */
+   memmap.map = early_ioremap((unsigned long)memmap.phys_map,
+  memmap.nr_map * memmap.desc_size);
+   if (memmap.map == NULL) {
+   pr_err("Could not map the memory map!\n");
+   return -ENOMEM;
+   }
+   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
+
+   set_bit(EFI_MEMMAP, _efi_facility);
+   return 0;
+}
+
 /*
  * Tell the kernel about the EFI memory map.  This might include
  * more than the max 128 entries that can fit in the e820 legacy
@@ -336,6 +354,9 @@ static void __init do_add_efi_memmap(void)
 {
void *p;
 
+   if (!efi_enabled(EFI_MEMMAP) && efi_memmap_init())
+   return;
+
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
efi_memory_desc_t *md = p;
unsigned long long start = md->phys_addr;
@@ -409,6 +430,9 @@ static void __init print_efi_memmap(void)
void *p;
int i;
 
+   if (!efi_enabled(EFI_MEMMAP))
+   return;
+
for (p = memmap.map, i = 0;
 p < memmap.map_end;
 p += memmap.desc_size, i++) {
@@ -687,23 +711,6 @@ static int __init efi_runtime_init(void)
return 0;
 }
 
-static int __init efi_memmap_init(void)
-{
-   /* Map the EFI memory map */
-   memmap.map = early_ioremap((unsigned long)memmap.phys_map,
-  memmap.nr_map * memmap.desc_size);
-   if (memmap.map == NULL) {
-   pr_err("Could not map the memory map!\n");
-   return -ENOMEM;
-   }
-   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
-
-   if (add_efi_memmap)
-   do_add_efi_memmap();
-
-   return 0;
-}
-
 void __init efi_init(void)
 {
efi_char16_t *c16;
@@ -766,7 +773,8 @@ void __init efi_init(void)
if (efi_memmap_init())
return;
 
-   set_bit(EFI_MEMMAP, _efi_facility);
+   if (add_efi_memmap)
+   do_add_efi_memmap();
 
 #ifdef CONFIG_X86_32
if (efi_is_native()) {
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 2/4] efi: Add memory_setup function efi_memory_setup()

2013-08-19 Thread Linn Crosetto
Adding efi_memory_setup() to be used to override the default
memory_setup function when the EFI memory map should be used instead of
a BIOS provided e820 map.

Signed-off-by: Linn Crosetto 
---
 arch/x86/platform/efi/efi.c | 8 
 include/linux/efi.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 32da922..c2a660c 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -711,6 +711,14 @@ static int __init efi_runtime_init(void)
return 0;
 }
 
+char * __init efi_memory_setup(void)
+{
+   char *who = "EFI";
+   efi_memmap_init();
+   do_add_efi_memmap();
+   return who;
+}
+
 void __init efi_init(void)
 {
efi_char16_t *c16;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 5f8f176..977bbc7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -567,6 +567,7 @@ efi_guid_unparse(efi_guid_t *guid, char *out)
 return out;
 }
 
+extern char *efi_memory_setup(void);
 extern void efi_init (void);
 extern void *efi_get_pal_addr (void);
 extern void efi_map_pal_code (void);
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 2/4] efi: Add memory_setup function efi_memory_setup()

2013-08-19 Thread Linn Crosetto
Adding efi_memory_setup() to be used to override the default
memory_setup function when the EFI memory map should be used instead of
a BIOS provided e820 map.

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/platform/efi/efi.c | 8 
 include/linux/efi.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 32da922..c2a660c 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -711,6 +711,14 @@ static int __init efi_runtime_init(void)
return 0;
 }
 
+char * __init efi_memory_setup(void)
+{
+   char *who = EFI;
+   efi_memmap_init();
+   do_add_efi_memmap();
+   return who;
+}
+
 void __init efi_init(void)
 {
efi_char16_t *c16;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 5f8f176..977bbc7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -567,6 +567,7 @@ efi_guid_unparse(efi_guid_t *guid, char *out)
 return out;
 }
 
+extern char *efi_memory_setup(void);
 extern void efi_init (void);
 extern void *efi_get_pal_addr (void);
 extern void efi_map_pal_code (void);
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 1/4] efi: Decouple efi_memmap_init() and do_add_efi_memmap()

2013-08-19 Thread Linn Crosetto
In order to enable the EFI memory map to be initialized outside of
efi_init(), decouple the two functions efi_memmap_init() and
do_add_efi_memmap() and set the x86_facility EFI_MEMMAP in
efi_memmap_init(). Additionally, check EFI_MEMMAP to determine whether
efi_memmap_init() has been previously called to avoid doing the
initialization more than once.

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/platform/efi/efi.c | 44 ++--
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 90f6ed1..32da922 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -326,6 +326,24 @@ void efi_get_time(struct timespec *now)
now-tv_nsec = 0;
 }
 
+static int __init efi_memmap_init(void)
+{
+   if (efi_enabled(EFI_MEMMAP))
+   return 0; /* already initialized */
+
+   /* Map the EFI memory map */
+   memmap.map = early_ioremap((unsigned long)memmap.phys_map,
+  memmap.nr_map * memmap.desc_size);
+   if (memmap.map == NULL) {
+   pr_err(Could not map the memory map!\n);
+   return -ENOMEM;
+   }
+   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
+
+   set_bit(EFI_MEMMAP, x86_efi_facility);
+   return 0;
+}
+
 /*
  * Tell the kernel about the EFI memory map.  This might include
  * more than the max 128 entries that can fit in the e820 legacy
@@ -336,6 +354,9 @@ static void __init do_add_efi_memmap(void)
 {
void *p;
 
+   if (!efi_enabled(EFI_MEMMAP)  efi_memmap_init())
+   return;
+
for (p = memmap.map; p  memmap.map_end; p += memmap.desc_size) {
efi_memory_desc_t *md = p;
unsigned long long start = md-phys_addr;
@@ -409,6 +430,9 @@ static void __init print_efi_memmap(void)
void *p;
int i;
 
+   if (!efi_enabled(EFI_MEMMAP))
+   return;
+
for (p = memmap.map, i = 0;
 p  memmap.map_end;
 p += memmap.desc_size, i++) {
@@ -687,23 +711,6 @@ static int __init efi_runtime_init(void)
return 0;
 }
 
-static int __init efi_memmap_init(void)
-{
-   /* Map the EFI memory map */
-   memmap.map = early_ioremap((unsigned long)memmap.phys_map,
-  memmap.nr_map * memmap.desc_size);
-   if (memmap.map == NULL) {
-   pr_err(Could not map the memory map!\n);
-   return -ENOMEM;
-   }
-   memmap.map_end = memmap.map + (memmap.nr_map * memmap.desc_size);
-
-   if (add_efi_memmap)
-   do_add_efi_memmap();
-
-   return 0;
-}
-
 void __init efi_init(void)
 {
efi_char16_t *c16;
@@ -766,7 +773,8 @@ void __init efi_init(void)
if (efi_memmap_init())
return;
 
-   set_bit(EFI_MEMMAP, x86_efi_facility);
+   if (add_efi_memmap)
+   do_add_efi_memmap();
 
 #ifdef CONFIG_X86_32
if (efi_is_native()) {
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 0/4] EFI boot stub memory map fix

2013-08-19 Thread Linn Crosetto
I realize the EFI stub for ARM patches are in flight, 

https://lkml.org/lkml/2013/8/9/554

and overlap with some of the files but I wanted to send these out for comment.

This series fixes a problem with EFI memory maps larger than 128 entries when
booting using the EFI boot stub, which results in overflowing the e820_map in
boot_params and an eventual halt when checking the map size in
sanitize_e820_map().

The fix implemented is to add the EFI memory map from setup_arch() via a
memory_setup hook.

Two options were considered:

 1. Use the SETUP_E820_EXT setup_data type to add the extra entries.

 2. Create a memory_setup function to be enabled when the EFI memory map is
needed.

Option 2 appeared to be the cleaner solution, reducing duplication with
existing code, given a reasonable mechanism for determining when to
replace the default memory_setup function.


Linn Crosetto (4):
  efi: Decouple efi_memmap_init() and do_add_efi_memmap()
  efi: Add memory_setup function efi_memory_setup()
  efi: Add efi_memmap_needed()
  x86: Fix EFI boot stub for large memory maps

 arch/x86/boot/compressed/eboot.c | 64 ++--
 arch/x86/kernel/setup.c  |  3 ++
 arch/x86/platform/efi/efi.c  | 51 +++-
 include/linux/efi.h  |  2 ++
 4 files changed, 45 insertions(+), 75 deletions(-)

-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 4/4] x86: Fix EFI boot stub for large memory maps

2013-08-19 Thread Linn Crosetto
This patch adds support for EFI memory maps larger than 128 entries when
booted using the EFI boot stub.

The e820 map in struct boot_params can only hold 128 entries, but the
memory map provided by EFI may be larger. If the map contained more than
128 entries, exit_boot() would write beyond the e820_map array in
boot_params and the system would eventually halt in the BUG_ON check in
sanitize_e820_map().

In the case we come in through efi_main(), the EFI memory map is used.
Instead of populating e820_map in boot_params, create the e820 from the
EFI memory map in setup_arch() via a memory_setup hook.

The EFI memory map may also be added in efi_init() if the command line
parameter add_efi_memmap is specified. This is left intact to allow
the command line parameter to remain effective.

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/boot/compressed/eboot.c | 64 ++--
 arch/x86/kernel/setup.c  |  3 ++
 2 files changed, 6 insertions(+), 61 deletions(-)

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a4..66b8d3d 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -973,6 +973,9 @@ struct boot_params *make_boot_params(void *handle, 
efi_system_table_t *_table)
if (status != EFI_SUCCESS)
goto fail2;
 
+   /* Use EFI memory map */
+   boot_params-e820_entries = 0;
+
return boot_params;
 fail2:
if (options_size)
@@ -986,8 +989,6 @@ static efi_status_t exit_boot(struct boot_params 
*boot_params,
  void *handle)
 {
struct efi_info *efi = boot_params-efi_info;
-   struct e820entry *e820_map = boot_params-e820_map[0];
-   struct e820entry *prev = NULL;
unsigned long size, key, desc_size, _size;
efi_memory_desc_t *mem_map;
efi_status_t status;
@@ -1049,65 +1050,6 @@ get_map:
/* Historic? */
boot_params-alt_mem_k = 32 * 1024;
 
-   /*
-* Convert the EFI memory map to E820.
-*/
-   nr_entries = 0;
-   for (i = 0; i  size / desc_size; i++) {
-   efi_memory_desc_t *d;
-   unsigned int e820_type = 0;
-   unsigned long m = (unsigned long)mem_map;
-
-   d = (efi_memory_desc_t *)(m + (i * desc_size));
-   switch (d-type) {
-   case EFI_RESERVED_TYPE:
-   case EFI_RUNTIME_SERVICES_CODE:
-   case EFI_RUNTIME_SERVICES_DATA:
-   case EFI_MEMORY_MAPPED_IO:
-   case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
-   case EFI_PAL_CODE:
-   e820_type = E820_RESERVED;
-   break;
-
-   case EFI_UNUSABLE_MEMORY:
-   e820_type = E820_UNUSABLE;
-   break;
-
-   case EFI_ACPI_RECLAIM_MEMORY:
-   e820_type = E820_ACPI;
-   break;
-
-   case EFI_LOADER_CODE:
-   case EFI_LOADER_DATA:
-   case EFI_BOOT_SERVICES_CODE:
-   case EFI_BOOT_SERVICES_DATA:
-   case EFI_CONVENTIONAL_MEMORY:
-   e820_type = E820_RAM;
-   break;
-
-   case EFI_ACPI_MEMORY_NVS:
-   e820_type = E820_NVS;
-   break;
-
-   default:
-   continue;
-   }
-
-   /* Merge adjacent mappings */
-   if (prev  prev-type == e820_type 
-   (prev-addr + prev-size) == d-phys_addr)
-   prev-size += d-num_pages  12;
-   else {
-   e820_map-addr = d-phys_addr;
-   e820_map-size = d-num_pages  12;
-   e820_map-type = e820_type;
-   prev = e820_map++;
-   nr_entries++;
-   }
-   }
-
-   boot_params-e820_entries = nr_entries;
-
return EFI_SUCCESS;
 
 free_mem_map:
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..9682c8c 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -920,6 +920,9 @@ void __init setup_arch(char **cmdline_p)
 
if (efi_enabled(EFI_BOOT))
efi_memblock_x86_reserve_range();
+
+   if (efi_memmap_needed())
+   x86_init.resources.memory_setup = efi_memory_setup;
 #endif
 
x86_init.oem.arch_setup();
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 3/4] efi: Add efi_memmap_needed()

2013-08-19 Thread Linn Crosetto
The function efi_memmap_needed() is used to determine when to use the
EFI memory map during boot instead of a BIOS provided e820.

The intent is to determine whether we are booted on an EFI system from
the EFI boot stub (came in through efi_main(), implemented by checking
efi_is_native() and the boot loader identifier), and that there is no
e820 map already provided.

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/platform/efi/efi.c | 7 +++
 include/linux/efi.h | 1 +
 2 files changed, 8 insertions(+)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index c2a660c..af32a21 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -719,6 +719,13 @@ char * __init efi_memory_setup(void)
return who;
 }
 
+int __init efi_memmap_needed(void)
+{
+   return efi_is_native() 
+  boot_params.e820_entries == 0 
+  boot_params.hdr.type_of_loader  4 == 2; /* bootsect-loader */
+}
+
 void __init efi_init(void)
 {
efi_char16_t *c16;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 977bbc7..95b2251 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -567,6 +567,7 @@ efi_guid_unparse(efi_guid_t *guid, char *out)
 return out;
 }
 
+extern int efi_memmap_needed(void);
 extern char *efi_memory_setup(void);
 extern void efi_init (void);
 extern void *efi_get_pal_addr (void);
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 0/4] EFI boot stub memory map fix

2013-08-19 Thread Linn Crosetto
On Mon, Aug 19, 2013 at 01:47:41PM -0700, Yinghai Lu wrote:
 On Mon, Aug 19, 2013 at 1:06 PM, H. Peter Anvin h...@zytor.com wrote:
  I would strongly disagree that option 2 is the cleaner solution.
 
 Agreed.
 
 
  Linn Crosetto l...@hp.com wrote:
 I realize the EFI stub for ARM patches are in flight,
 
 https://lkml.org/lkml/2013/8/9/554
 
 and overlap with some of the files but I wanted to send these out for
 comment.
 
 This series fixes a problem with EFI memory maps larger than 128
 entries when
 booting using the EFI boot stub, which results in overflowing the
 e820_map in
 boot_params and an eventual halt when checking the map size in
 sanitize_e820_map().
 
 The fix implemented is to add the EFI memory map from setup_arch() via
 a
 memory_setup hook.
 
 Two options were considered:
 
  1. Use the SETUP_E820_EXT setup_data type to add the extra entries.
 
 2. Create a memory_setup function to be enabled when the EFI memory map
 is
 needed.
 
 Option 2 appeared to be the cleaner solution, reducing duplication with
 existing code, given a reasonable mechanism for determining when to
 replace the default memory_setup function.
 
 If boot_loader could create setup_data with SETUP_E820_EXT,
 efi_stub should go that path too.
 We should not add another path.

My consideration was in leveraging do_add_efi_memmap(), which duplicates what is
done with the map in exit_boot(), and can already be called via the
add_efi_memmap parameter. One complication with SETUP_E820_EXT is in
determining the size needed, since a call to allocate_pool will change the
memory map. 

I will send another version which uses SETUP_E820_EXT.

Thanks,
Linn
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] x86: avoid remapping data in parse_setup_data()

2013-08-13 Thread Linn Crosetto
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.

Signed-off-by: Linn Crosetto 
---
v3: Remove data remapping code from parse_setup_data() and add it to
parse_e820_ext().

 arch/x86/include/asm/e820.h |  2 +-
 arch/x86/kernel/e820.c  |  5 -
 arch/x86/kernel/setup.c | 19 ---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index cccd07f..779c2ef 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data);
+extern void parse_e820_ext(u64 phys_addr, u32 data_len);
 
 #if defined(CONFIG_X86_64) || \
(defined(CONFIG_X86_32) && defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d32abea..174da5f 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata)
+void __init parse_e820_ext(u64 phys_addr, u32 data_len)
 {
int entries;
struct e820entry *extmap;
+   struct setup_data *sdata;
 
+   sdata = early_memremap(phys_addr, data_len);
entries = sdata->len / sizeof(struct e820entry);
extmap = (struct e820entry *)(sdata->data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), _map);
+   early_iounmap(sdata, data_len);
printk(KERN_INFO "e820: extended physical RAM map:\n");
e820_print_map("extended");
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..234e1e3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void)
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
-   u64 pa_data;
+   u64 pa_data, pa_next;
 
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
-   u32 data_len, map_len;
+   u32 data_len, map_len, data_type;
 
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
-   if (data_len > map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
+   data_type = data->type;
+   pa_next = data->next;
+   early_iounmap(data, map_len);
 
-   switch (data->type) {
+   switch (data_type) {
case SETUP_E820_EXT:
-   parse_e820_ext(data);
+   parse_e820_ext(pa_data, data_len);
break;
case SETUP_DTB:
add_dtb(pa_data);
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void)
default:
break;
}
-   pa_data = data->next;
-   early_iounmap(data, map_len);
+   pa_data = pa_next;
}
 }
 
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3] x86: avoid remapping data in parse_setup_data()

2013-08-13 Thread Linn Crosetto
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.

Signed-off-by: Linn Crosetto l...@hp.com
---
v3: Remove data remapping code from parse_setup_data() and add it to
parse_e820_ext().

 arch/x86/include/asm/e820.h |  2 +-
 arch/x86/kernel/e820.c  |  5 -
 arch/x86/kernel/setup.c | 19 ---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index cccd07f..779c2ef 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -29,7 +29,7 @@ extern void e820_setup_gap(void);
 extern int e820_search_gap(unsigned long *gapstart, unsigned long *gapsize,
unsigned long start_addr, unsigned long long end_addr);
 struct setup_data;
-extern void parse_e820_ext(struct setup_data *data);
+extern void parse_e820_ext(u64 phys_addr, u32 data_len);
 
 #if defined(CONFIG_X86_64) || \
(defined(CONFIG_X86_32)  defined(CONFIG_HIBERNATION))
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index d32abea..174da5f 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void)
  * boot_params.e820_map, others are passed via SETUP_E820_EXT node of
  * linked list of struct setup_data, which is parsed here.
  */
-void __init parse_e820_ext(struct setup_data *sdata)
+void __init parse_e820_ext(u64 phys_addr, u32 data_len)
 {
int entries;
struct e820entry *extmap;
+   struct setup_data *sdata;
 
+   sdata = early_memremap(phys_addr, data_len);
entries = sdata-len / sizeof(struct e820entry);
extmap = (struct e820entry *)(sdata-data);
__append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), e820.nr_map);
+   early_iounmap(sdata, data_len);
printk(KERN_INFO e820: extended physical RAM map:\n);
e820_print_map(extended);
 }
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..234e1e3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,25 +426,23 @@ static void __init reserve_initrd(void)
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
-   u64 pa_data;
+   u64 pa_data, pa_next;
 
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
-   u32 data_len, map_len;
+   u32 data_len, map_len, data_type;
 
map_len = max(PAGE_SIZE - (pa_data  ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data-len + sizeof(struct setup_data);
-   if (data_len  map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
+   data_type = data-type;
+   pa_next = data-next;
+   early_iounmap(data, map_len);
 
-   switch (data-type) {
+   switch (data_type) {
case SETUP_E820_EXT:
-   parse_e820_ext(data);
+   parse_e820_ext(pa_data, data_len);
break;
case SETUP_DTB:
add_dtb(pa_data);
@@ -452,8 +450,7 @@ static void __init parse_setup_data(void)
default:
break;
}
-   pa_data = data-next;
-   early_iounmap(data, map_len);
+   pa_data = pa_next;
}
 }
 
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] x86: selective remapping in parse_setup_data()

2013-08-12 Thread Linn Crosetto
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, first remap the setup_data header, and remap the data
only for types actually parsed in parse_setup_data(). Type SETUP_PCI is
handled later by pcibios_add_device(), when ioremap() is available.

Signed-off-by: Linn Crosetto 
---
v2: add more detail to the explanation as requested by hpa
---
 arch/x86/kernel/setup.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..2063a49 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -423,6 +423,17 @@ static void __init reserve_initrd(void)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+static void __init remap_setup_data(u64 pa_data, u32 data_len,
+   struct setup_data **data, u32 *map_len)
+{
+   if (data_len <= *map_len)
+   return;
+
+   early_iounmap(*data, *map_len);
+   *data = early_memremap(pa_data, data_len);
+   *map_len = data_len;
+}
+
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
@@ -432,18 +443,16 @@ static void __init parse_setup_data(void)
while (pa_data) {
u32 data_len, map_len;
 
+   /* The data length may be too large for early remapping,
+  remap the data only when needed. */
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
-   if (data_len > map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
 
switch (data->type) {
case SETUP_E820_EXT:
+   remap_setup_data(pa_data, data_len, , _len);
parse_e820_ext(data);
break;
case SETUP_DTB:
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] x86: selective remapping in parse_setup_data()

2013-08-12 Thread Linn Crosetto
PCI devices may advertise a ROM size larger than early_memremap() is
able to handle. If this occurs it leads to a NULL dereference in
parse_setup_data(). Avoid this by remapping the data only when
necessary.

Signed-off-by: Linn Crosetto 
---
 arch/x86/kernel/setup.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..2063a49 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -423,6 +423,17 @@ static void __init reserve_initrd(void)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+static void __init remap_setup_data(u64 pa_data, u32 data_len,
+   struct setup_data **data, u32 *map_len)
+{
+   if (data_len <= *map_len)
+   return;
+
+   early_iounmap(*data, *map_len);
+   *data = early_memremap(pa_data, data_len);
+   *map_len = data_len;
+}
+
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
@@ -432,18 +443,16 @@ static void __init parse_setup_data(void)
while (pa_data) {
u32 data_len, map_len;
 
+   /* The data length may be too large for early remapping,
+  remap the data only when needed. */
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
-   if (data_len > map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
 
switch (data->type) {
case SETUP_E820_EXT:
+   remap_setup_data(pa_data, data_len, , _len);
parse_e820_ext(data);
break;
case SETUP_DTB:
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] x86: selective remapping in parse_setup_data()

2013-08-12 Thread Linn Crosetto
PCI devices may advertise a ROM size larger than early_memremap() is
able to handle. If this occurs it leads to a NULL dereference in
parse_setup_data(). Avoid this by remapping the data only when
necessary.

Signed-off-by: Linn Crosetto l...@hp.com
---
 arch/x86/kernel/setup.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..2063a49 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -423,6 +423,17 @@ static void __init reserve_initrd(void)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+static void __init remap_setup_data(u64 pa_data, u32 data_len,
+   struct setup_data **data, u32 *map_len)
+{
+   if (data_len = *map_len)
+   return;
+
+   early_iounmap(*data, *map_len);
+   *data = early_memremap(pa_data, data_len);
+   *map_len = data_len;
+}
+
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
@@ -432,18 +443,16 @@ static void __init parse_setup_data(void)
while (pa_data) {
u32 data_len, map_len;
 
+   /* The data length may be too large for early remapping,
+  remap the data only when needed. */
map_len = max(PAGE_SIZE - (pa_data  ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data-len + sizeof(struct setup_data);
-   if (data_len  map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
 
switch (data-type) {
case SETUP_E820_EXT:
+   remap_setup_data(pa_data, data_len, data, map_len);
parse_e820_ext(data);
break;
case SETUP_DTB:
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] x86: selective remapping in parse_setup_data()

2013-08-12 Thread Linn Crosetto
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().

To avoid this, first remap the setup_data header, and remap the data
only for types actually parsed in parse_setup_data(). Type SETUP_PCI is
handled later by pcibios_add_device(), when ioremap() is available.

Signed-off-by: Linn Crosetto l...@hp.com
---
v2: add more detail to the explanation as requested by hpa
---
 arch/x86/kernel/setup.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..2063a49 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -423,6 +423,17 @@ static void __init reserve_initrd(void)
 }
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+static void __init remap_setup_data(u64 pa_data, u32 data_len,
+   struct setup_data **data, u32 *map_len)
+{
+   if (data_len = *map_len)
+   return;
+
+   early_iounmap(*data, *map_len);
+   *data = early_memremap(pa_data, data_len);
+   *map_len = data_len;
+}
+
 static void __init parse_setup_data(void)
 {
struct setup_data *data;
@@ -432,18 +443,16 @@ static void __init parse_setup_data(void)
while (pa_data) {
u32 data_len, map_len;
 
+   /* The data length may be too large for early remapping,
+  remap the data only when needed. */
map_len = max(PAGE_SIZE - (pa_data  ~PAGE_MASK),
  (u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data-len + sizeof(struct setup_data);
-   if (data_len  map_len) {
-   early_iounmap(data, map_len);
-   data = early_memremap(pa_data, data_len);
-   map_len = data_len;
-   }
 
switch (data-type) {
case SETUP_E820_EXT:
+   remap_setup_data(pa_data, data_len, data, map_len);
parse_e820_ext(data);
break;
case SETUP_DTB:
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/mm] x86/iommu/dmar: Remove warning for HPET scope type

2013-04-24 Thread tip-bot for Linn Crosetto
Commit-ID:  13f72756da86f155898e2c2022f7b3a106c3742e
Gitweb: http://git.kernel.org/tip/13f72756da86f155898e2c2022f7b3a106c3742e
Author: Linn Crosetto 
AuthorDate: Tue, 23 Apr 2013 12:26:45 -0600
Committer:  Ingo Molnar 
CommitDate: Wed, 24 Apr 2013 08:45:47 +0200

x86/iommu/dmar: Remove warning for HPET scope type

ACPI_DMAR_SCOPE_TYPE_HPET is parsed by
ir_parse_ioapic_hpet_scope() and should not be flagged as an
unsupported type.

Signed-off-by: Linn Crosetto 
Cc: j...@8bytes.org
Cc: ddut...@redhat.com
Cc: suresh.b.sid...@intel.com
Link: http://lkml.kernel.org/r/1366741605-71293-1-git-send-email-l...@hp.com
Signed-off-by: Ingo Molnar 
---
 drivers/iommu/dmar.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e5cdaf8..b8008f6 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -129,7 +129,8 @@ int __init dmar_parse_dev_scope(void *start, void *end, int 
*cnt,
if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++;
-   else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
+   else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC &&
+   scope->entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
pr_warn("Unsupported device scope\n");
}
start += scope->length;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[tip:x86/mm] x86/iommu/dmar: Remove warning for HPET scope type

2013-04-24 Thread tip-bot for Linn Crosetto
Commit-ID:  13f72756da86f155898e2c2022f7b3a106c3742e
Gitweb: http://git.kernel.org/tip/13f72756da86f155898e2c2022f7b3a106c3742e
Author: Linn Crosetto l...@hp.com
AuthorDate: Tue, 23 Apr 2013 12:26:45 -0600
Committer:  Ingo Molnar mi...@kernel.org
CommitDate: Wed, 24 Apr 2013 08:45:47 +0200

x86/iommu/dmar: Remove warning for HPET scope type

ACPI_DMAR_SCOPE_TYPE_HPET is parsed by
ir_parse_ioapic_hpet_scope() and should not be flagged as an
unsupported type.

Signed-off-by: Linn Crosetto l...@hp.com
Cc: j...@8bytes.org
Cc: ddut...@redhat.com
Cc: suresh.b.sid...@intel.com
Link: http://lkml.kernel.org/r/1366741605-71293-1-git-send-email-l...@hp.com
Signed-off-by: Ingo Molnar mi...@kernel.org
---
 drivers/iommu/dmar.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e5cdaf8..b8008f6 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -129,7 +129,8 @@ int __init dmar_parse_dev_scope(void *start, void *end, int 
*cnt,
if (scope-entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope-entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++;
-   else if (scope-entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
+   else if (scope-entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC 
+   scope-entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
pr_warn(Unsupported device scope\n);
}
start += scope-length;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] iommu: dmar -- remove warning for HPET scope type

2013-04-23 Thread Linn Crosetto
ACPI_DMAR_SCOPE_TYPE_HPET is parsed by ir_parse_ioapic_hpet_scope() and
should not be flagged as an unsupported type.

Signed-off-by: Linn Crosetto 
---
 drivers/iommu/dmar.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e5cdaf8..b8008f6 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -129,7 +129,8 @@ int __init dmar_parse_dev_scope(void *start, void *end, int 
*cnt,
if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++;
-   else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
+   else if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC &&
+   scope->entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
pr_warn("Unsupported device scope\n");
}
start += scope->length;
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] iommu: dmar -- remove warning for HPET scope type

2013-04-23 Thread Linn Crosetto
ACPI_DMAR_SCOPE_TYPE_HPET is parsed by ir_parse_ioapic_hpet_scope() and
should not be flagged as an unsupported type.

Signed-off-by: Linn Crosetto l...@hp.com
---
 drivers/iommu/dmar.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e5cdaf8..b8008f6 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -129,7 +129,8 @@ int __init dmar_parse_dev_scope(void *start, void *end, int 
*cnt,
if (scope-entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope-entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++;
-   else if (scope-entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
+   else if (scope-entry_type != ACPI_DMAR_SCOPE_TYPE_IOAPIC 
+   scope-entry_type != ACPI_DMAR_SCOPE_TYPE_HPET) {
pr_warn(Unsupported device scope\n);
}
start += scope-length;
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] acpi: remove length check for large registers

2013-03-15 Thread Linn Crosetto
On Fri, Mar 15, 2013 at 08:50:45PM +, Moore, Robert wrote:
> Can you explain in a bit more detail what brings this up?
> 
> I'm aware of the limitation of the generic address structure, but we are 
> forced by the (current) ACPI specification to use it if it is present for a 
> given register.

A system with a GPE block bit_width of 256 triggers it. In this case, the length
check can never succeed.

Thanks,
Linn
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] acpi: remove length check for large registers

2013-03-15 Thread Linn Crosetto
The legacy bit width field in the Generic Address Structure is 1 byte,
limiting the reportable register width to 255 bits. Larger registers
will cause a length mismatch warning to be printed in
acpi_tb_validate_fadt().

To avoid the warning, disable the length mismatch check for registers
larger than 255 bits.

Signed-off-by: Linn Crosetto 
---
 drivers/acpi/acpica/tbfadt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 74181bf..e87abcd 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -561,6 +561,7 @@ static void acpi_tb_validate_fadt(void)
 * legacy length field and the corresponding 64-bit X length 
field.
 */
if (address64->address &&
+   ACPI_MUL_8(length) <= ACPI_UINT8_MAX &&
(address64->bit_width != ACPI_MUL_8(length))) {
ACPI_BIOS_WARNING((AE_INFO,
   "32/64X length mismatch in FADT/%s: 
%u/%u",
-- 
1.7.11.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] acpi: remove length check for large registers

2013-03-15 Thread Linn Crosetto
The legacy bit width field in the Generic Address Structure is 1 byte,
limiting the reportable register width to 255 bits. Larger registers
will cause a length mismatch warning to be printed in
acpi_tb_validate_fadt().

To avoid the warning, disable the length mismatch check for registers
larger than 255 bits.

Signed-off-by: Linn Crosetto l...@hp.com
---
 drivers/acpi/acpica/tbfadt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 74181bf..e87abcd 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -561,6 +561,7 @@ static void acpi_tb_validate_fadt(void)
 * legacy length field and the corresponding 64-bit X length 
field.
 */
if (address64-address 
+   ACPI_MUL_8(length) = ACPI_UINT8_MAX 
(address64-bit_width != ACPI_MUL_8(length))) {
ACPI_BIOS_WARNING((AE_INFO,
   32/64X length mismatch in FADT/%s: 
%u/%u,
-- 
1.7.11.3

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] acpi: remove length check for large registers

2013-03-15 Thread Linn Crosetto
On Fri, Mar 15, 2013 at 08:50:45PM +, Moore, Robert wrote:
 Can you explain in a bit more detail what brings this up?
 
 I'm aware of the limitation of the generic address structure, but we are 
 forced by the (current) ACPI specification to use it if it is present for a 
 given register.

A system with a GPE block bit_width of 256 triggers it. In this case, the length
check can never succeed.

Thanks,
Linn
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/