diff mbox

[PATCHv2,1/5] efi/runtime-wrappers: add {__,}efi_call_virt templates

Message ID 1461238529-12810-2-git-send-email-mark.rutland@arm.com
State Superseded
Headers show

Commit Message

Mark Rutland April 21, 2016, 11:35 a.m. UTC
Currently each architecture must implement two macros, efi_call_virt and
__efi_call_virt, which only differ by the presence or absence of a
return type. Otherwise, the logic surrounding the call is identical.

As each architecture must define the entire body of each, we can't place
any generic manipulation (e.g. irq flag validation) in the middle.

This patch adds template implementations of these macros. With these,
arch code can implement three template macros, avoiding reptition for
the void/non-void return cases:

* arch_efi_call_virt_setup

  Sets up the environment for the call (e.g. switching page tables,
  allowing kernel-mode use of floating point, if required).

* arch_efi_call_virt

  Performs the call. The last expression in the macro must be the call
  itself, allowing the logic to be shared by the void and non-void
  cases.

* arch_efi_call_virt_teardown

  Restores the usual kernel environment once the call has returned.

While the savings from repition are minimal, we additionally gain the
ability to add common code around the call with the call enviroment set
up. This can be used to detect common firmware issues (e.g. bad irq mask
management).

Signed-off-by: Mark Rutland <mark.rutland@arm.com>

Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: linux-efi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/firmware/efi/runtime-wrappers.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

-- 
1.9.1

Comments

Leif Lindholm April 21, 2016, 11:42 a.m. UTC | #1
On Thu, Apr 21, 2016 at 12:35:25PM +0100, Mark Rutland wrote:
> Currently each architecture must implement two macros, efi_call_virt and

> __efi_call_virt, which only differ by the presence or absence of a

> return type. Otherwise, the logic surrounding the call is identical.

> 

> As each architecture must define the entire body of each, we can't place

> any generic manipulation (e.g. irq flag validation) in the middle.

> 

> This patch adds template implementations of these macros. With these,

> arch code can implement three template macros, avoiding reptition for

> the void/non-void return cases:

> 

> * arch_efi_call_virt_setup

> 

>   Sets up the environment for the call (e.g. switching page tables,

>   allowing kernel-mode use of floating point, if required).

> 

> * arch_efi_call_virt

> 

>   Performs the call. The last expression in the macro must be the call

>   itself, allowing the logic to be shared by the void and non-void

>   cases.

> 

> * arch_efi_call_virt_teardown

> 

>   Restores the usual kernel environment once the call has returned.

> 

> While the savings from repition are minimal, we additionally gain the

> ability to add common code around the call with the call enviroment set

> up. This can be used to detect common firmware issues (e.g. bad irq mask

> management).

> 

> Signed-off-by: Mark Rutland <mark.rutland@arm.com>

> Cc: Matt Fleming <matt@codeblueprint.co.uk>

> Cc: linux-efi@vger.kernel.org

> Cc: linux-kernel@vger.kernel.org

> ---

>  drivers/firmware/efi/runtime-wrappers.c | 21 +++++++++++++++++++++

>  1 file changed, 21 insertions(+)

> 

> diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c

> index de69530..1b9fa54 100644

> --- a/drivers/firmware/efi/runtime-wrappers.c

> +++ b/drivers/firmware/efi/runtime-wrappers.c

> @@ -20,6 +20,27 @@

>  #include <linux/spinlock.h>

>  #include <asm/efi.h>

>  

> +

> +#ifndef efi_call_virt


So ... not a strong complaint, but I would prefer if these weren't
ifdefd. I presume this is because ia64?
Could that be given a dummy pass-through version instead? If not,
could a comment be added that this is to retain compatibility with
ia64 (so that if that architecture was to mysteriously disappear from
the tree, someone might remember to deconditionalise it)?

> +#define efi_call_virt(f, args...)					\

> +({									\

> +	efi_status_t __s;						\

> +	arch_efi_call_virt_setup();					\

> +	__s = arch_efi_call_virt(f, args);				\

> +	arch_efi_call_virt_teardown();					\

> +	__s;								\

> +})

> +#endif

> +

> +#ifndef __efi_call_virt

> +#define __efi_call_virt(f, args...)					\

> +({									\

> +	arch_efi_call_virt_setup();					\

> +	arch_efi_call_virt(f, args);					\

> +	arch_efi_call_virt_teardown();					\

> +})

> +#endif

> +

>  /*

>   * According to section 7.1 of the UEFI spec, Runtime Services are not fully

>   * reentrant, and there are particular combinations of calls that need to be

> -- 

> 1.9.1

>
Mark Rutland April 21, 2016, 12:55 p.m. UTC | #2
On Thu, Apr 21, 2016 at 12:42:56PM +0100, Leif Lindholm wrote:
> On Thu, Apr 21, 2016 at 12:35:25PM +0100, Mark Rutland wrote:

> > Currently each architecture must implement two macros, efi_call_virt and

> > __efi_call_virt, which only differ by the presence or absence of a

> > return type. Otherwise, the logic surrounding the call is identical.

> > 

> > As each architecture must define the entire body of each, we can't place

> > any generic manipulation (e.g. irq flag validation) in the middle.

> > 

> > This patch adds template implementations of these macros. With these,

> > arch code can implement three template macros, avoiding reptition for

> > the void/non-void return cases:

> > 

> > * arch_efi_call_virt_setup

> > 

> >   Sets up the environment for the call (e.g. switching page tables,

> >   allowing kernel-mode use of floating point, if required).

> > 

> > * arch_efi_call_virt

> > 

> >   Performs the call. The last expression in the macro must be the call

> >   itself, allowing the logic to be shared by the void and non-void

> >   cases.

> > 

> > * arch_efi_call_virt_teardown

> > 

> >   Restores the usual kernel environment once the call has returned.

> > 

> > While the savings from repition are minimal, we additionally gain the

> > ability to add common code around the call with the call enviroment set

> > up. This can be used to detect common firmware issues (e.g. bad irq mask

> > management).

> > 

> > Signed-off-by: Mark Rutland <mark.rutland@arm.com>

> > Cc: Matt Fleming <matt@codeblueprint.co.uk>

> > Cc: linux-efi@vger.kernel.org

> > Cc: linux-kernel@vger.kernel.org

> > ---

> >  drivers/firmware/efi/runtime-wrappers.c | 21 +++++++++++++++++++++

> >  1 file changed, 21 insertions(+)

> > 

> > diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c

> > index de69530..1b9fa54 100644

> > --- a/drivers/firmware/efi/runtime-wrappers.c

> > +++ b/drivers/firmware/efi/runtime-wrappers.c

> > @@ -20,6 +20,27 @@

> >  #include <linux/spinlock.h>

> >  #include <asm/efi.h>

> >  

> > +

> > +#ifndef efi_call_virt

> 

> So ... not a strong complaint, but I would prefer if these weren't

> ifdefd. I presume this is because ia64?


Yup, and to allow the gradual migration of arm/arm64/x86 without a new
CONFIG_WANT_GENERIC_EFI_CALL_VIRT or something to that effect.

> Could that be given a dummy pass-through version instead?


I'm not exactly sure what you mean by that. Could you elaborate?

> If not, could a comment be added that this is to retain compatibility

> with ia64 (so that if that architecture was to mysteriously disappear

> from the tree, someone might remember to deconditionalise it)?


Sure. I can also add a note to the commit message regarding the
temporary need while arm/arm64/x86 are moved over.

Thanks,
Mark.

> > +#define efi_call_virt(f, args...)					\

> > +({									\

> > +	efi_status_t __s;						\

> > +	arch_efi_call_virt_setup();					\

> > +	__s = arch_efi_call_virt(f, args);				\

> > +	arch_efi_call_virt_teardown();					\

> > +	__s;								\

> > +})

> > +#endif

> > +

> > +#ifndef __efi_call_virt

> > +#define __efi_call_virt(f, args...)					\

> > +({									\

> > +	arch_efi_call_virt_setup();					\

> > +	arch_efi_call_virt(f, args);					\

> > +	arch_efi_call_virt_teardown();					\

> > +})

> > +#endif

> > +

> >  /*

> >   * According to section 7.1 of the UEFI spec, Runtime Services are not fully

> >   * reentrant, and there are particular combinations of calls that need to be

> > -- 

> > 1.9.1

> > 

>
Mark Rutland April 21, 2016, 2:19 p.m. UTC | #3
On Thu, Apr 21, 2016 at 01:55:07PM +0100, Mark Rutland wrote:
> On Thu, Apr 21, 2016 at 12:42:56PM +0100, Leif Lindholm wrote:

> > On Thu, Apr 21, 2016 at 12:35:25PM +0100, Mark Rutland wrote:

> > > Currently each architecture must implement two macros, efi_call_virt and

> > > __efi_call_virt, which only differ by the presence or absence of a

> > > return type. Otherwise, the logic surrounding the call is identical.

> > > 

> > > As each architecture must define the entire body of each, we can't place

> > > any generic manipulation (e.g. irq flag validation) in the middle.

> > > 

> > > This patch adds template implementations of these macros. With these,

> > > arch code can implement three template macros, avoiding reptition for

> > > the void/non-void return cases:

> > > 

> > > * arch_efi_call_virt_setup

> > > 

> > >   Sets up the environment for the call (e.g. switching page tables,

> > >   allowing kernel-mode use of floating point, if required).

> > > 

> > > * arch_efi_call_virt

> > > 

> > >   Performs the call. The last expression in the macro must be the call

> > >   itself, allowing the logic to be shared by the void and non-void

> > >   cases.

> > > 

> > > * arch_efi_call_virt_teardown

> > > 

> > >   Restores the usual kernel environment once the call has returned.

> > > 

> > > While the savings from repition are minimal, we additionally gain the

> > > ability to add common code around the call with the call enviroment set

> > > up. This can be used to detect common firmware issues (e.g. bad irq mask

> > > management).

> > > 

> > > Signed-off-by: Mark Rutland <mark.rutland@arm.com>

> > > Cc: Matt Fleming <matt@codeblueprint.co.uk>

> > > Cc: linux-efi@vger.kernel.org

> > > Cc: linux-kernel@vger.kernel.org

> > > ---

> > >  drivers/firmware/efi/runtime-wrappers.c | 21 +++++++++++++++++++++

> > >  1 file changed, 21 insertions(+)

> > > 

> > > diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c

> > > index de69530..1b9fa54 100644

> > > --- a/drivers/firmware/efi/runtime-wrappers.c

> > > +++ b/drivers/firmware/efi/runtime-wrappers.c

> > > @@ -20,6 +20,27 @@

> > >  #include <linux/spinlock.h>

> > >  #include <asm/efi.h>

> > >  

> > > +

> > > +#ifndef efi_call_virt

> > 

> > So ... not a strong complaint, but I would prefer if these weren't

> > ifdefd. I presume this is because ia64?

> 

> Yup, and to allow the gradual migration of arm/arm64/x86 without a new

> CONFIG_WANT_GENERIC_EFI_CALL_VIRT or something to that effect.


Actually, ia64 never uses this code, so I can add a final patch to
remove the ifdefs after the existing arch code is moved over.

I'll do that...

Mark.
diff mbox

Patch

diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index de69530..1b9fa54 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -20,6 +20,27 @@ 
 #include <linux/spinlock.h>
 #include <asm/efi.h>
 
+
+#ifndef efi_call_virt
+#define efi_call_virt(f, args...)					\
+({									\
+	efi_status_t __s;						\
+	arch_efi_call_virt_setup();					\
+	__s = arch_efi_call_virt(f, args);				\
+	arch_efi_call_virt_teardown();					\
+	__s;								\
+})
+#endif
+
+#ifndef __efi_call_virt
+#define __efi_call_virt(f, args...)					\
+({									\
+	arch_efi_call_virt_setup();					\
+	arch_efi_call_virt(f, args);					\
+	arch_efi_call_virt_teardown();					\
+})
+#endif
+
 /*
  * According to section 7.1 of the UEFI spec, Runtime Services are not fully
  * reentrant, and there are particular combinations of calls that need to be