Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-15 Thread Ard Biesheuvel
On 14 July 2018 at 13:41, Lukas Wunner  wrote:
> On Fri, Jul 13, 2018 at 03:54:29PM +0200, Ard Biesheuvel wrote:
>> Did you have any thoughts about how we could at least detect
>> situations where we are invoking protocols that are not mixed-mode
>> safe (i.e., they pass 64-bit quantities by value, which our current
>> thunking routine does not take into account)
>
> efi_thunk_64.S only supports five arguments AFAICS, we'd have to check
> for each argument passed to efi_call_early() or efi_call_proto() if
> the corresponding argument in the *_32_t protocol struct has sizeof(u64),
> and BUILD_BUG_ON() if so.
>
> Is it possible to retrieve the n-th element of a struct without knowing
> its name?  Basically offsetof() but with a number instead of a name?
> We have to check the size of the struct element, not the argument passed
> in to efi_call_early() / efi_call_proto() because we pass in 64-bit
> pointers (and possibly also integers) and fully expect that the upper
> 32-bit are disregarded.
>
> Difficult. :-(
>

Yeah. I think a GCC plugin is the only way to achieve this.
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-14 Thread Lukas Wunner
On Fri, Jul 13, 2018 at 03:54:29PM +0200, Ard Biesheuvel wrote:
> Did you have any thoughts about how we could at least detect
> situations where we are invoking protocols that are not mixed-mode
> safe (i.e., they pass 64-bit quantities by value, which our current
> thunking routine does not take into account)

efi_thunk_64.S only supports five arguments AFAICS, we'd have to check
for each argument passed to efi_call_early() or efi_call_proto() if
the corresponding argument in the *_32_t protocol struct has sizeof(u64),
and BUILD_BUG_ON() if so.

Is it possible to retrieve the n-th element of a struct without knowing
its name?  Basically offsetof() but with a number instead of a name?
We have to check the size of the struct element, not the argument passed
in to efi_call_early() / efi_call_proto() because we pass in 64-bit
pointers (and possibly also integers) and fully expect that the upper
32-bit are disregarded.

Difficult. :-(

Lukas
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-13 Thread Ard Biesheuvel
On 13 July 2018 at 11:57, Lukas Wunner  wrote:
> On Thu, Jul 12, 2018 at 02:21:48PM +0200, Ard Biesheuvel wrote:
>> Patch #2 merges the remaining 32/64-bit specific parts of the setup_efi_pci
>> routine.
>>
>> Patches #3 and #4 do the same for the UGA draw protocol discovery routines.
>>
>> Patch #6 helps unused code paths to be optimized away on configurations
>> that don't need them (32-bit only and 64-bit only)
>
> Thanks a lot for doing this Ard, I meant to deduplicate that code
> further but didn't get around to it.  FWIW I have a single unsubmitted
> deduplication patch which has been rotting on my development branch for
> more than a year now, I'm including it below in case it helps, needs a
> careful review though.
>

Thanks Lukas. I will apply that (with Ingo's comment addressed).

Did you have any thoughts about how we could at least detect
situations where we are invoking protocols that are not mixed-mode
safe (i.e., they pass 64-bit quantities by value, which our current
thunking routine does not take into account)


> -- >8 --
> From 7fa51faec20c74eea2bb3ba96ecab1bc3e18e5a8 Mon Sep 17 00:00:00 2001
> From: Lukas Wunner 
> Date: Sun, 7 May 2017 14:42:51 +0200
> Subject: [PATCH] efi: Deduplicate efi_open_volume()
>
> There's one ARM, one x86_32 and one x86_64 version which can be folded
> into a single shared version by masking their differences with the
> efi_call_proto() macro introduced by commit 3552fdf29f01 ("efi: Allow
> bitness-agnostic protocol calls").
>
> To be able to dereference the device_handle attribute from the
> efi_loaded_image_t table in an arch- and bitness-agnostic manner,
> introduce the efi_table_attr() macro (which already exists for x86)
> to arm and arm64.
>
> No functional change intended.
>
> Signed-off-by: Lukas Wunner 
> ---
>  arch/arm/include/asm/efi.h |  3 ++
>  arch/arm64/include/asm/efi.h   |  3 ++
>  arch/x86/boot/compressed/eboot.c   | 61 
> --
>  drivers/firmware/efi/libstub/arm-stub.c| 25 ---
>  drivers/firmware/efi/libstub/efi-stub-helper.c | 29 +++-
>  drivers/firmware/efi/libstub/efistub.h |  3 --
>  include/linux/efi.h| 10 +
>  7 files changed, 43 insertions(+), 91 deletions(-)
>
> diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
> index 17f1f1a..38badaa 100644
> --- a/arch/arm/include/asm/efi.h
> +++ b/arch/arm/include/asm/efi.h
> @@ -58,6 +58,9 @@ static inline void efi_set_pgd(struct mm_struct *mm)
>  #define efi_call_runtime(f, ...)   sys_table_arg->runtime->f(__VA_ARGS__)
>  #define efi_is_64bit() (false)
>
> +#define efi_table_attr(table, attr, instance)  \
> +   ((table##_t *)instance)->attr
> +
>  #define efi_call_proto(protocol, f, instance, ...) \
> ((protocol##_t *)instance)->f(instance, ##__VA_ARGS__)
>
> diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
> index c4cd508..5a21037 100644
> --- a/arch/arm64/include/asm/efi.h
> +++ b/arch/arm64/include/asm/efi.h
> @@ -85,6 +85,9 @@ static inline unsigned long 
> efi_get_max_initrd_addr(unsigned long dram_base,
>  #define efi_call_runtime(f, ...)   sys_table_arg->runtime->f(__VA_ARGS__)
>  #define efi_is_64bit() (true)
>
> +#define efi_table_attr(table, attr, instance)  \
> +   ((table##_t *)instance)->attr
> +
>  #define efi_call_proto(protocol, f, instance, ...) \
> ((protocol##_t *)instance)->f(instance, ##__VA_ARGS__)
>
> diff --git a/arch/x86/boot/compressed/eboot.c 
> b/arch/x86/boot/compressed/eboot.c
> index 9a5b6d3..2d2b599 100644
> --- a/arch/x86/boot/compressed/eboot.c
> +++ b/arch/x86/boot/compressed/eboot.c
> @@ -41,67 +41,6 @@ __pure const struct efi_config *__efi_early(void)
>  BOOT_SERVICES(32);
>  BOOT_SERVICES(64);
>
> -static inline efi_status_t __open_volume32(void *__image, void **__fh)
> -{
> -   efi_file_io_interface_t *io;
> -   efi_loaded_image_32_t *image = __image;
> -   efi_file_handle_32_t *fh;
> -   efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
> -   efi_status_t status;
> -   void *handle = (void *)(unsigned long)image->device_handle;
> -   unsigned long func;
> -
> -   status = efi_call_early(handle_protocol, handle,
> -   _proto, (void **));
> -   if (status != EFI_SUCCESS) {
> -   efi_printk(sys_table, "Failed to handle fs_proto\n");
> -   return status;
> -   }
> -
> -   func = (unsigned long)io->open_volume;
> -   status = efi_early->call(func, io, );
> -   if (status != EFI_SUCCESS)
> -   efi_printk(sys_table, "Failed to open volume\n");
> -
> -   *__fh = fh;
> -   return status;
> -}
> -
> -static inline efi_status_t __open_volume64(void *__image, void **__fh)
> -{
> -   efi_file_io_interface_t *io;
> -   

Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-13 Thread Ard Biesheuvel
On 13 July 2018 at 15:29, Ingo Molnar  wrote:
>
> * Lukas Wunner  wrote:
>
>> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
>> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
>> @@ -413,6 +413,32 @@ static efi_status_t efi_file_close(void *handle)
>>   return efi_call_proto(efi_file_handle, close, handle);
>>  }
>>
>> +static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
>> + efi_loaded_image_t *image,
>> + efi_file_handle_t **__fh)
>> +{
>> + efi_file_io_interface_t *io;
>> + efi_file_handle_t *fh;
>> + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
>> + efi_status_t status;
>> + void *handle =
>> + (void *)efi_table_attr(efi_loaded_image, device_handle, image);
>> +
>> + status = efi_call_early(handle_protocol, handle,
>> + _proto, (void **));
>> + if (status != EFI_SUCCESS) {
>> + efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
>> + return status;
>> + }
>> +
>> + status = efi_call_proto(efi_file_io_interface, open_volume, io, );
>> + if (status != EFI_SUCCESS)
>> + efi_printk(sys_table_arg, "Failed to open volume\n");
>> +
>> + *__fh = fh;
>> + return status;
>
> BTW., in the second failure branch is 'fh' guaranteed to be set by the EFI 
> call?
> If not then we set *__fh to a potentially undefined value, from the kernels 
> stack?
>
> (I realize that your refactoring just inherited this existing pattern, but it
> caught my attention.)
>

No, only EFI_SUCCESS guarantees that fh will have been assigned.

Since we propagate 'status' here, it does not seem to matter in
practice, but it would indeed be better not to clobber *__fh with
random junk when returning failure.
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-13 Thread Ingo Molnar


* Lukas Wunner  wrote:

> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
> @@ -413,6 +413,32 @@ static efi_status_t efi_file_close(void *handle)
>   return efi_call_proto(efi_file_handle, close, handle);
>  }
>  
> +static efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
> + efi_loaded_image_t *image,
> + efi_file_handle_t **__fh)
> +{
> + efi_file_io_interface_t *io;
> + efi_file_handle_t *fh;
> + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
> + efi_status_t status;
> + void *handle =
> + (void *)efi_table_attr(efi_loaded_image, device_handle, image);
> +
> + status = efi_call_early(handle_protocol, handle,
> + _proto, (void **));
> + if (status != EFI_SUCCESS) {
> + efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
> + return status;
> + }
> +
> + status = efi_call_proto(efi_file_io_interface, open_volume, io, );
> + if (status != EFI_SUCCESS)
> + efi_printk(sys_table_arg, "Failed to open volume\n");
> +
> + *__fh = fh;
> + return status;

BTW., in the second failure branch is 'fh' guaranteed to be set by the EFI 
call? 
If not then we set *__fh to a potentially undefined value, from the kernels 
stack?

(I realize that your refactoring just inherited this existing pattern, but it 
caught my attention.)

Thanks,

Ingo
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-13 Thread Lukas Wunner
On Thu, Jul 12, 2018 at 02:21:48PM +0200, Ard Biesheuvel wrote:
> Patch #2 merges the remaining 32/64-bit specific parts of the setup_efi_pci
> routine.
> 
> Patches #3 and #4 do the same for the UGA draw protocol discovery routines.
> 
> Patch #6 helps unused code paths to be optimized away on configurations
> that don't need them (32-bit only and 64-bit only)

Thanks a lot for doing this Ard, I meant to deduplicate that code
further but didn't get around to it.  FWIW I have a single unsubmitted
deduplication patch which has been rotting on my development branch for
more than a year now, I'm including it below in case it helps, needs a
careful review though.

-- >8 --
>From 7fa51faec20c74eea2bb3ba96ecab1bc3e18e5a8 Mon Sep 17 00:00:00 2001
From: Lukas Wunner 
Date: Sun, 7 May 2017 14:42:51 +0200
Subject: [PATCH] efi: Deduplicate efi_open_volume()

There's one ARM, one x86_32 and one x86_64 version which can be folded
into a single shared version by masking their differences with the
efi_call_proto() macro introduced by commit 3552fdf29f01 ("efi: Allow
bitness-agnostic protocol calls").

To be able to dereference the device_handle attribute from the
efi_loaded_image_t table in an arch- and bitness-agnostic manner,
introduce the efi_table_attr() macro (which already exists for x86)
to arm and arm64.

No functional change intended.

Signed-off-by: Lukas Wunner 
---
 arch/arm/include/asm/efi.h |  3 ++
 arch/arm64/include/asm/efi.h   |  3 ++
 arch/x86/boot/compressed/eboot.c   | 61 --
 drivers/firmware/efi/libstub/arm-stub.c| 25 ---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 29 +++-
 drivers/firmware/efi/libstub/efistub.h |  3 --
 include/linux/efi.h| 10 +
 7 files changed, 43 insertions(+), 91 deletions(-)

diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h
index 17f1f1a..38badaa 100644
--- a/arch/arm/include/asm/efi.h
+++ b/arch/arm/include/asm/efi.h
@@ -58,6 +58,9 @@ static inline void efi_set_pgd(struct mm_struct *mm)
 #define efi_call_runtime(f, ...)   sys_table_arg->runtime->f(__VA_ARGS__)
 #define efi_is_64bit() (false)
 
+#define efi_table_attr(table, attr, instance)  \
+   ((table##_t *)instance)->attr
+
 #define efi_call_proto(protocol, f, instance, ...) \
((protocol##_t *)instance)->f(instance, ##__VA_ARGS__)
 
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index c4cd508..5a21037 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -85,6 +85,9 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned 
long dram_base,
 #define efi_call_runtime(f, ...)   sys_table_arg->runtime->f(__VA_ARGS__)
 #define efi_is_64bit() (true)
 
+#define efi_table_attr(table, attr, instance)  \
+   ((table##_t *)instance)->attr
+
 #define efi_call_proto(protocol, f, instance, ...) \
((protocol##_t *)instance)->f(instance, ##__VA_ARGS__)
 
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 9a5b6d3..2d2b599 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -41,67 +41,6 @@ __pure const struct efi_config *__efi_early(void)
 BOOT_SERVICES(32);
 BOOT_SERVICES(64);
 
-static inline efi_status_t __open_volume32(void *__image, void **__fh)
-{
-   efi_file_io_interface_t *io;
-   efi_loaded_image_32_t *image = __image;
-   efi_file_handle_32_t *fh;
-   efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
-   efi_status_t status;
-   void *handle = (void *)(unsigned long)image->device_handle;
-   unsigned long func;
-
-   status = efi_call_early(handle_protocol, handle,
-   _proto, (void **));
-   if (status != EFI_SUCCESS) {
-   efi_printk(sys_table, "Failed to handle fs_proto\n");
-   return status;
-   }
-
-   func = (unsigned long)io->open_volume;
-   status = efi_early->call(func, io, );
-   if (status != EFI_SUCCESS)
-   efi_printk(sys_table, "Failed to open volume\n");
-
-   *__fh = fh;
-   return status;
-}
-
-static inline efi_status_t __open_volume64(void *__image, void **__fh)
-{
-   efi_file_io_interface_t *io;
-   efi_loaded_image_64_t *image = __image;
-   efi_file_handle_64_t *fh;
-   efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
-   efi_status_t status;
-   void *handle = (void *)(unsigned long)image->device_handle;
-   unsigned long func;
-
-   status = efi_call_early(handle_protocol, handle,
-   _proto, (void **));
-   if (status != EFI_SUCCESS) {
-   efi_printk(sys_table, "Failed to handle fs_proto\n");
-   return status;
-   }
-
-   func = (unsigned long)io->open_volume;

RE: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-12 Thread Prakhya, Sai Praneeth
> >> Patch #6 helps unused code paths to be optimized away on
> >> configurations that don't need them (32-bit only and 64-bit only)
> >
> > I have tested this patch set on qemu and I see mixed mode kernel not 
> > booting.
> > My test setup is:
> > Running qemu-system-x86_64 with 32 bit OVMF and x86_64 kernel built with
> Mixed mode enabled.
> > I am using elilinux as bootloader.
> >
> > Upon further investigation, I found that the issue isn't related to this 
> > patch set.
> > It's introduced with commit 2e6eb40ca5eb ("Fix incorrect invocation of
> > PciIO->Attributes") Reverting the change does help in booting mixed mode
> kernel.
> >
> 
> Hello Sai,
> 
> This is likely due to the fact that you are missing this patch
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?h=efi/urgen
> t=e296701800f30d260a66f8aa1971b5b1bc3d2f81
> 
> Could you please double check? Thanks.

Thanks for updating me on this. I now see why my testing broke.
I think, the above patch is only in TIP tree and didn't yet make to Linus's 
tree and is also not part of efi tree next branch (these were the trees I am 
testing on).

Regards,
Sai


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-12 Thread Ard Biesheuvel
On 13 July 2018 at 03:59, Prakhya, Sai Praneeth
 wrote:
> Hi Ard,
>
>> This series contains some fixes and cleanups for mixed-mode UEFI on x86.
>>
>> Patch #1 adds the missing locking in the runtime service wrapper code for 
>> mixed
>> mode. This was found by inspection rather than having been reported but could
>> be a candidate for -stable nonetheless.
>>
>> Patch #2 merges the remaining 32/64-bit specific parts of the setup_efi_pci
>> routine.
>>
>> Patches #3 and #4 do the same for the UGA draw protocol discovery routines.
>>
>> Patch #5 fixes a latent bug in the UGA draw code.
>>
>> Patch #6 helps unused code paths to be optimized away on configurations that
>> don't need them (32-bit only and 64-bit only)
>
> I have tested this patch set on qemu and I see mixed mode kernel not booting.
> My test setup is:
> Running qemu-system-x86_64 with 32 bit OVMF and x86_64 kernel built with 
> Mixed mode enabled.
> I am using elilinux as bootloader.
>
> Upon further investigation, I found that the issue isn't related to this 
> patch set.
> It's introduced with commit 2e6eb40ca5eb ("Fix incorrect invocation of 
> PciIO->Attributes")
> Reverting the change does help in booting mixed mode kernel.
>

Hello Sai,

This is likely due to the fact that you are missing this patch

https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?h=efi/urgent=e296701800f30d260a66f8aa1971b5b1bc3d2f81

Could you please double check? Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-12 Thread Prakhya, Sai Praneeth
Hi Ard,

> This series contains some fixes and cleanups for mixed-mode UEFI on x86.
> 
> Patch #1 adds the missing locking in the runtime service wrapper code for 
> mixed
> mode. This was found by inspection rather than having been reported but could
> be a candidate for -stable nonetheless.
> 
> Patch #2 merges the remaining 32/64-bit specific parts of the setup_efi_pci
> routine.
> 
> Patches #3 and #4 do the same for the UGA draw protocol discovery routines.
> 
> Patch #5 fixes a latent bug in the UGA draw code.
> 
> Patch #6 helps unused code paths to be optimized away on configurations that
> don't need them (32-bit only and 64-bit only)

I have tested this patch set on qemu and I see mixed mode kernel not booting.
My test setup is:
Running qemu-system-x86_64 with 32 bit OVMF and x86_64 kernel built with Mixed 
mode enabled.
I am using elilinux as bootloader.

Upon further investigation, I found that the issue isn't related to this patch 
set.
It's introduced with commit 2e6eb40ca5eb ("Fix incorrect invocation of 
PciIO->Attributes")
Reverting the change does help in booting mixed mode kernel.

Regards,
Sai
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-12 Thread Ard Biesheuvel
On 12 July 2018 at 16:26, Hans de Goede  wrote:
> Hi,
>
> On 12-07-18 14:21, Ard Biesheuvel wrote:
>>
>> This series contains some fixes and cleanups for mixed-mode UEFI on x86.
>>
>> Patch #1 adds the missing locking in the runtime service wrapper code for
>> mixed mode. This was found by inspection rather than having been reported
>> but could be a candidate for -stable nonetheless.
>>
>> Patch #2 merges the remaining 32/64-bit specific parts of the
>> setup_efi_pci
>> routine.
>>
>> Patches #3 and #4 do the same for the UGA draw protocol discovery
>> routines.
>>
>> Patch #5 fixes a latent bug in the UGA draw code.
>>
>> Patch #6 helps unused code paths to be optimized away on configurations
>> that don't need them (32-bit only and 64-bit only)
>
>
> I've given a kernel with these patches a quick spin running in mixed
> mode on a Bay Trail based tablet:
>
> Tested-by: Hans de Goede 
>

Thanks Hans, much appreciated.
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/6] efi/x86 mixed mode cleanups

2018-07-12 Thread Hans de Goede

Hi,

On 12-07-18 14:21, Ard Biesheuvel wrote:

This series contains some fixes and cleanups for mixed-mode UEFI on x86.

Patch #1 adds the missing locking in the runtime service wrapper code for
mixed mode. This was found by inspection rather than having been reported
but could be a candidate for -stable nonetheless.

Patch #2 merges the remaining 32/64-bit specific parts of the setup_efi_pci
routine.

Patches #3 and #4 do the same for the UGA draw protocol discovery routines.

Patch #5 fixes a latent bug in the UGA draw code.

Patch #6 helps unused code paths to be optimized away on configurations
that don't need them (32-bit only and 64-bit only)


I've given a kernel with these patches a quick spin running in mixed
mode on a Bay Trail based tablet:

Tested-by: Hans de Goede 

Regards,

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html