diff mbox series

[2/4] efi/arm: defer persistent reservations until after paging_init()

Message ID 20181106113732.16351-3-ard.biesheuvel@linaro.org
State New
Headers show
Series arm/efi: fix memblock reallocation crash due to persistent reservations | expand

Commit Message

Ard Biesheuvel Nov. 6, 2018, 11:37 a.m. UTC
The new memory EFI reservation feature we introduced to allow memory
reservations to persist across kexec may trigger an unbounded number
of calls to memblock_reserve(). The memblock subsystem can deal with
this fine, but not before memblock resizing is enabled, which we can
only do after paging_init(), when the memory we reallocate the array
into is actually mapped.

So break out the memreserve table processing into a separate function
and call if after paging_init() on both arm64 and ARM.

Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 arch/arm/kernel/setup.c    | 1 +
 arch/arm64/kernel/setup.c  | 1 +
 drivers/firmware/efi/efi.c | 8 ++++++--
 include/linux/efi.h        | 7 +++++++
 4 files changed, 15 insertions(+), 2 deletions(-)

-- 
2.19.1

Comments

Ard Biesheuvel Nov. 6, 2018, 7:02 p.m. UTC | #1
On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> The new memory EFI reservation feature we introduced to allow memory

> reservations to persist across kexec may trigger an unbounded number

> of calls to memblock_reserve(). The memblock subsystem can deal with

> this fine, but not before memblock resizing is enabled, which we can

> only do after paging_init(), when the memory we reallocate the array

> into is actually mapped.

>

> So break out the memreserve table processing into a separate function

> and call if after paging_init() on both arm64 and ARM.

>

> Cc: Russell King <linux@armlinux.org.uk>

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>


Russell,

If you are ok with this patch, may I have your ack please? I would
like to send it out before the end of the week.

Thanks,

> ---

>  arch/arm/kernel/setup.c    | 1 +

>  arch/arm64/kernel/setup.c  | 1 +

>  drivers/firmware/efi/efi.c | 8 ++++++--

>  include/linux/efi.h        | 7 +++++++

>  4 files changed, 15 insertions(+), 2 deletions(-)

>

> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c

> index ac7e08886863..e99f12eaf390 100644

> --- a/arch/arm/kernel/setup.c

> +++ b/arch/arm/kernel/setup.c

> @@ -1117,6 +1117,7 @@ void __init setup_arch(char **cmdline_p)

>         early_ioremap_reset();

>

>         paging_init(mdesc);

> +       efi_apply_persistent_mem_reservations();

>         request_standard_resources(mdesc);

>

>         if (mdesc->restart)

> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c

> index 953e316521fc..f4fc1e0544b7 100644

> --- a/arch/arm64/kernel/setup.c

> +++ b/arch/arm64/kernel/setup.c

> @@ -313,6 +313,7 @@ void __init setup_arch(char **cmdline_p)

>         arm64_memblock_init();

>

>         paging_init();

> +       efi_apply_persistent_mem_reservations();

>

>         acpi_table_upgrade();

>

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

> index 249eb70691b0..55e4ea20bdc3 100644

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

> +++ b/drivers/firmware/efi/efi.c

> @@ -592,7 +592,11 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,

>

>                 early_memunmap(tbl, sizeof(*tbl));

>         }

> +       return 0;

> +}

>

> +int __init efi_apply_persistent_mem_reservations(void)

> +{

>         if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {

>                 unsigned long prsv = efi.mem_reserve;

>

> @@ -602,7 +606,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,

>                         /* reserve the entry itself */

>                         memblock_reserve(prsv, sizeof(*rsv));

>

> -                       rsv = early_memremap(prsv, sizeof(*rsv));

> +                       rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);

>                         if (rsv == NULL) {

>                                 pr_err("Could not map UEFI memreserve entry!\n");

>                                 return -ENOMEM;

> @@ -612,7 +616,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,

>                                 memblock_reserve(rsv->base, rsv->size);

>

>                         prsv = rsv->next;

> -                       early_memunmap(rsv, sizeof(*rsv));

> +                       memunmap(rsv);

>                 }

>         }

>

> diff --git a/include/linux/efi.h b/include/linux/efi.h

> index 845174e113ce..100ce4a4aff6 100644

> --- a/include/linux/efi.h

> +++ b/include/linux/efi.h

> @@ -1167,6 +1167,8 @@ static inline bool efi_enabled(int feature)

>  extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);

>

>  extern bool efi_is_table_address(unsigned long phys_addr);

> +

> +extern int efi_apply_persistent_mem_reservations(void);

>  #else

>  static inline bool efi_enabled(int feature)

>  {

> @@ -1185,6 +1187,11 @@ static inline bool efi_is_table_address(unsigned long phys_addr)

>  {

>         return false;

>  }

> +

> +static inline int efi_apply_persistent_mem_reservations(void)

> +{

> +       return 0;

> +}

>  #endif

>

>  extern int efi_status_to_err(efi_status_t status);

> --

> 2.19.1

>
Russell King (Oracle) Nov. 6, 2018, 7:08 p.m. UTC | #2
On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:
> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> > The new memory EFI reservation feature we introduced to allow memory

> > reservations to persist across kexec may trigger an unbounded number

> > of calls to memblock_reserve(). The memblock subsystem can deal with

> > this fine, but not before memblock resizing is enabled, which we can

> > only do after paging_init(), when the memory we reallocate the array

> > into is actually mapped.

> >

> > So break out the memreserve table processing into a separate function

> > and call if after paging_init() on both arm64 and ARM.

> >

> > Cc: Russell King <linux@armlinux.org.uk>

> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> 

> Russell,

> 

> If you are ok with this patch, may I have your ack please? I would

> like to send it out before the end of the week.


You're not going to get a quick answer to this, because it needs me to
investigate what the effect of this change actually is by code review.
I can't guarantee when I'll get around to that.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
Ard Biesheuvel Nov. 6, 2018, 8:06 p.m. UTC | #3
On 6 November 2018 at 20:08, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

>> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

>> > The new memory EFI reservation feature we introduced to allow memory

>> > reservations to persist across kexec may trigger an unbounded number

>> > of calls to memblock_reserve(). The memblock subsystem can deal with

>> > this fine, but not before memblock resizing is enabled, which we can

>> > only do after paging_init(), when the memory we reallocate the array

>> > into is actually mapped.

>> >

>> > So break out the memreserve table processing into a separate function

>> > and call if after paging_init() on both arm64 and ARM.

>> >

>> > Cc: Russell King <linux@armlinux.org.uk>

>> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>>

>> Russell,

>>

>> If you are ok with this patch, may I have your ack please? I would

>> like to send it out before the end of the week.

>

> You're not going to get a quick answer to this, because it needs me to

> investigate what the effect of this change actually is by code review.

> I can't guarantee when I'll get around to that.

>


Fair enough.

I will drop the ARM hunk for now then, and we'll fix ARM when you have
more time.

Thanks,
Russell King (Oracle) Nov. 6, 2018, 11:49 p.m. UTC | #4
On Tue, Nov 06, 2018 at 09:06:56PM +0100, Ard Biesheuvel wrote:
> On 6 November 2018 at 20:08, Russell King - ARM Linux

> <linux@armlinux.org.uk> wrote:

> > On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

> >> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >> > The new memory EFI reservation feature we introduced to allow memory

> >> > reservations to persist across kexec may trigger an unbounded number

> >> > of calls to memblock_reserve(). The memblock subsystem can deal with

> >> > this fine, but not before memblock resizing is enabled, which we can

> >> > only do after paging_init(), when the memory we reallocate the array

> >> > into is actually mapped.

> >> >

> >> > So break out the memreserve table processing into a separate function

> >> > and call if after paging_init() on both arm64 and ARM.

> >> >

> >> > Cc: Russell King <linux@armlinux.org.uk>

> >> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> >>

> >> Russell,

> >>

> >> If you are ok with this patch, may I have your ack please? I would

> >> like to send it out before the end of the week.

> >

> > You're not going to get a quick answer to this, because it needs me to

> > investigate what the effect of this change actually is by code review.

> > I can't guarantee when I'll get around to that.

> >

> 

> Fair enough.

> 

> I will drop the ARM hunk for now then, and we'll fix ARM when you have

> more time.


I don't see how you can do that - you're dropping the processing of
reserved areas out of the efi_config_parse_tables() path, so that
won't happen any more on ARM if you don't apply the ARM hunk.

So what I see at the moment is that efi_config_parse_tables() is
called prior to paging_init() - and prior to our memblock
initialisation, and you're proposing to move the processing that
marks blocks as reserved immediately after paging_init(), and
to use the normal memremap() interface to map stuff.

I'm not convinced this will work - the memory allocators have not
been setup at this point, so using memremap() will try to allocate
page tables and potentially fail.  If the normal allocators are
setup, it's way too late to be calling memblock_reserve() - the
memory will have been passed over to the page allocator according
to which memblocks are available but not reserved.

The normal page allocator is setup by mem_init(), which happens
way after setup_arch() has returned.

So, I don't see how your patch can be correct at the moment.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
Marc Zyngier Nov. 7, 2018, 9:51 a.m. UTC | #5
On 06/11/18 23:49, Russell King - ARM Linux wrote:
> On Tue, Nov 06, 2018 at 09:06:56PM +0100, Ard Biesheuvel wrote:

>> On 6 November 2018 at 20:08, Russell King - ARM Linux

>> <linux@armlinux.org.uk> wrote:

>>> On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

>>>> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

>>>>> The new memory EFI reservation feature we introduced to allow memory

>>>>> reservations to persist across kexec may trigger an unbounded number

>>>>> of calls to memblock_reserve(). The memblock subsystem can deal with

>>>>> this fine, but not before memblock resizing is enabled, which we can

>>>>> only do after paging_init(), when the memory we reallocate the array

>>>>> into is actually mapped.

>>>>>

>>>>> So break out the memreserve table processing into a separate function

>>>>> and call if after paging_init() on both arm64 and ARM.

>>>>>

>>>>> Cc: Russell King <linux@armlinux.org.uk>

>>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>>>>

>>>> Russell,

>>>>

>>>> If you are ok with this patch, may I have your ack please? I would

>>>> like to send it out before the end of the week.

>>>

>>> You're not going to get a quick answer to this, because it needs me to

>>> investigate what the effect of this change actually is by code review.

>>> I can't guarantee when I'll get around to that.

>>>

>>

>> Fair enough.

>>

>> I will drop the ARM hunk for now then, and we'll fix ARM when you have

>> more time.

> 

> I don't see how you can do that - you're dropping the processing of

> reserved areas out of the efi_config_parse_tables() path, so that

> won't happen any more on ARM if you don't apply the ARM hunk.


The only reason for the whole persistent region thing is to support 
GICv3 redistributors memory tables across kexec, for those GIC 
implementations where LPIs cannot be disabled once they have been 
enabled.

There is no HW platform that combines 32bit cores and GICv3 (not to 
mention using EFI). The only existing "platform" is KVM/arm64, which 
doesn't suffer from the above problem (LPIs can be freely disabled in 
emulation). So the whole persistent region feature serves no purpose on 
32bit ARM.

The only issue with dropping this hunk is that the memory reservation 
feature is enabled on 32bit ARM the first place, which can easily be 
dealt with something along those lines:

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 787d7850e064..8bb263c9b99a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1290,6 +1290,7 @@ config EFI
 	select EFI_RUNTIME_WRAPPERS
 	select EFI_STUB
 	select EFI_ARMSTUB
+	select EFI_PERSISTENT_RESERVATIONS
 	default y
 	help
 	  This option provides support for runtime services provided
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 89110dfc7127..b728dab9e901 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -198,3 +198,6 @@ config EFI_DEV_PATH_PARSER
 	bool
 	depends on ACPI
 	default n
+
+config EFI_PERSISTENT_RESERVATIONS
+       bool
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 249eb70691b0..2a1903ab6d21 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -962,6 +962,7 @@ bool efi_is_table_address(unsigned long phys_addr)
 	return false;
 }
 
+#ifdef CONFIG_EFI_PERSISTENT_RESERVATIONS
 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
 
 int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
@@ -993,6 +994,12 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 
 	return 0;
 }
+#else
+int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+{
+	return 0;
+}
+#endif
 
 #ifdef CONFIG_KEXEC
 static int update_efi_random_seed(struct notifier_block *nb,

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...
Russell King (Oracle) Nov. 7, 2018, 9:58 a.m. UTC | #6
On Wed, Nov 07, 2018 at 09:51:09AM +0000, Marc Zyngier wrote:
> On 06/11/18 23:49, Russell King - ARM Linux wrote:

> > On Tue, Nov 06, 2018 at 09:06:56PM +0100, Ard Biesheuvel wrote:

> >> On 6 November 2018 at 20:08, Russell King - ARM Linux

> >> <linux@armlinux.org.uk> wrote:

> >>> On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

> >>>> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >>>>> The new memory EFI reservation feature we introduced to allow memory

> >>>>> reservations to persist across kexec may trigger an unbounded number

> >>>>> of calls to memblock_reserve(). The memblock subsystem can deal with

> >>>>> this fine, but not before memblock resizing is enabled, which we can

> >>>>> only do after paging_init(), when the memory we reallocate the array

> >>>>> into is actually mapped.

> >>>>>

> >>>>> So break out the memreserve table processing into a separate function

> >>>>> and call if after paging_init() on both arm64 and ARM.

> >>>>>

> >>>>> Cc: Russell King <linux@armlinux.org.uk>

> >>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> >>>>

> >>>> Russell,

> >>>>

> >>>> If you are ok with this patch, may I have your ack please? I would

> >>>> like to send it out before the end of the week.

> >>>

> >>> You're not going to get a quick answer to this, because it needs me to

> >>> investigate what the effect of this change actually is by code review.

> >>> I can't guarantee when I'll get around to that.

> >>>

> >>

> >> Fair enough.

> >>

> >> I will drop the ARM hunk for now then, and we'll fix ARM when you have

> >> more time.

> > 

> > I don't see how you can do that - you're dropping the processing of

> > reserved areas out of the efi_config_parse_tables() path, so that

> > won't happen any more on ARM if you don't apply the ARM hunk.

> 

> The only reason for the whole persistent region thing is to support 

> GICv3 redistributors memory tables across kexec, for those GIC 

> implementations where LPIs cannot be disabled once they have been 

> enabled.

> 

> There is no HW platform that combines 32bit cores and GICv3 (not to 

> mention using EFI). The only existing "platform" is KVM/arm64, which 

> doesn't suffer from the above problem (LPIs can be freely disabled in 

> emulation). So the whole persistent region feature serves no purpose on 

> 32bit ARM.

> 

> The only issue with dropping this hunk is that the memory reservation 

> feature is enabled on 32bit ARM the first place, which can easily be 

> dealt with something along those lines:


So, it was a waste of my time trying to understand what's going on here
with Ard's patch because it shouldn't be present on 32-bit ARM... Grr.

> 

> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig

> index 787d7850e064..8bb263c9b99a 100644

> --- a/arch/arm64/Kconfig

> +++ b/arch/arm64/Kconfig

> @@ -1290,6 +1290,7 @@ config EFI

>  	select EFI_RUNTIME_WRAPPERS

>  	select EFI_STUB

>  	select EFI_ARMSTUB

> +	select EFI_PERSISTENT_RESERVATIONS

>  	default y

>  	help

>  	  This option provides support for runtime services provided

> diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig

> index 89110dfc7127..b728dab9e901 100644

> --- a/drivers/firmware/efi/Kconfig

> +++ b/drivers/firmware/efi/Kconfig

> @@ -198,3 +198,6 @@ config EFI_DEV_PATH_PARSER

>  	bool

>  	depends on ACPI

>  	default n

> +

> +config EFI_PERSISTENT_RESERVATIONS

> +       bool

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

> index 249eb70691b0..2a1903ab6d21 100644

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

> +++ b/drivers/firmware/efi/efi.c

> @@ -962,6 +962,7 @@ bool efi_is_table_address(unsigned long phys_addr)

>  	return false;

>  }

>  

> +#ifdef CONFIG_EFI_PERSISTENT_RESERVATIONS

>  static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);

>  

>  int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)

> @@ -993,6 +994,12 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)

>  

>  	return 0;

>  }

> +#else

> +int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)

> +{

> +	return 0;

> +}

> +#endif

>  

>  #ifdef CONFIG_KEXEC

>  static int update_efi_random_seed(struct notifier_block *nb,

> 

> Thanks,

> 

> 	M.

> -- 

> Jazz is not dead. It just smells funny...


-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
Ard Biesheuvel Nov. 7, 2018, 10:04 a.m. UTC | #7
On 7 November 2018 at 10:58, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Wed, Nov 07, 2018 at 09:51:09AM +0000, Marc Zyngier wrote:

>> On 06/11/18 23:49, Russell King - ARM Linux wrote:

>> > On Tue, Nov 06, 2018 at 09:06:56PM +0100, Ard Biesheuvel wrote:

>> >> On 6 November 2018 at 20:08, Russell King - ARM Linux

>> >> <linux@armlinux.org.uk> wrote:

>> >>> On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

>> >>>> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

>> >>>>> The new memory EFI reservation feature we introduced to allow memory

>> >>>>> reservations to persist across kexec may trigger an unbounded number

>> >>>>> of calls to memblock_reserve(). The memblock subsystem can deal with

>> >>>>> this fine, but not before memblock resizing is enabled, which we can

>> >>>>> only do after paging_init(), when the memory we reallocate the array

>> >>>>> into is actually mapped.

>> >>>>>

>> >>>>> So break out the memreserve table processing into a separate function

>> >>>>> and call if after paging_init() on both arm64 and ARM.

>> >>>>>

>> >>>>> Cc: Russell King <linux@armlinux.org.uk>

>> >>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

>> >>>>

>> >>>> Russell,

>> >>>>

>> >>>> If you are ok with this patch, may I have your ack please? I would

>> >>>> like to send it out before the end of the week.

>> >>>

>> >>> You're not going to get a quick answer to this, because it needs me to

>> >>> investigate what the effect of this change actually is by code review.

>> >>> I can't guarantee when I'll get around to that.

>> >>>

>> >>

>> >> Fair enough.

>> >>

>> >> I will drop the ARM hunk for now then, and we'll fix ARM when you have

>> >> more time.

>> >

>> > I don't see how you can do that - you're dropping the processing of

>> > reserved areas out of the efi_config_parse_tables() path, so that

>> > won't happen any more on ARM if you don't apply the ARM hunk.

>>

>> The only reason for the whole persistent region thing is to support

>> GICv3 redistributors memory tables across kexec, for those GIC

>> implementations where LPIs cannot be disabled once they have been

>> enabled.

>>

>> There is no HW platform that combines 32bit cores and GICv3 (not to

>> mention using EFI). The only existing "platform" is KVM/arm64, which

>> doesn't suffer from the above problem (LPIs can be freely disabled in

>> emulation). So the whole persistent region feature serves no purpose on

>> 32bit ARM.

>>

>> The only issue with dropping this hunk is that the memory reservation

>> feature is enabled on 32bit ARM the first place, which can easily be

>> dealt with something along those lines:

>

> So, it was a waste of my time trying to understand what's going on here

> with Ard's patch because it shouldn't be present on 32-bit ARM... Grr.

>


Not really. I am trying really hard to do my part when it comes to
keeping the maintenance level of the ARM architecture up. That means
that all the improvements and enhancements that are implemented for
EFI on arm64 are enabled on ARM as well, unless there are pressing
reasons not to.

And even though this persistent reservation feature is only used by
the GICv3 code at the moment, there may be other future uses as well,
so I'd prefer not to special case ARM in this way.
Russell King (Oracle) Nov. 7, 2018, 10:24 a.m. UTC | #8
On Wed, Nov 07, 2018 at 11:04:53AM +0100, Ard Biesheuvel wrote:
> On 7 November 2018 at 10:58, Russell King - ARM Linux

> <linux@armlinux.org.uk> wrote:

> > On Wed, Nov 07, 2018 at 09:51:09AM +0000, Marc Zyngier wrote:

> >> On 06/11/18 23:49, Russell King - ARM Linux wrote:

> >> > On Tue, Nov 06, 2018 at 09:06:56PM +0100, Ard Biesheuvel wrote:

> >> >> On 6 November 2018 at 20:08, Russell King - ARM Linux

> >> >> <linux@armlinux.org.uk> wrote:

> >> >>> On Tue, Nov 06, 2018 at 08:02:58PM +0100, Ard Biesheuvel wrote:

> >> >>>> On 6 November 2018 at 12:37, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:

> >> >>>>> The new memory EFI reservation feature we introduced to allow memory

> >> >>>>> reservations to persist across kexec may trigger an unbounded number

> >> >>>>> of calls to memblock_reserve(). The memblock subsystem can deal with

> >> >>>>> this fine, but not before memblock resizing is enabled, which we can

> >> >>>>> only do after paging_init(), when the memory we reallocate the array

> >> >>>>> into is actually mapped.

> >> >>>>>

> >> >>>>> So break out the memreserve table processing into a separate function

> >> >>>>> and call if after paging_init() on both arm64 and ARM.

> >> >>>>>

> >> >>>>> Cc: Russell King <linux@armlinux.org.uk>

> >> >>>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> >> >>>>

> >> >>>> Russell,

> >> >>>>

> >> >>>> If you are ok with this patch, may I have your ack please? I would

> >> >>>> like to send it out before the end of the week.

> >> >>>

> >> >>> You're not going to get a quick answer to this, because it needs me to

> >> >>> investigate what the effect of this change actually is by code review.

> >> >>> I can't guarantee when I'll get around to that.

> >> >>>

> >> >>

> >> >> Fair enough.

> >> >>

> >> >> I will drop the ARM hunk for now then, and we'll fix ARM when you have

> >> >> more time.

> >> >

> >> > I don't see how you can do that - you're dropping the processing of

> >> > reserved areas out of the efi_config_parse_tables() path, so that

> >> > won't happen any more on ARM if you don't apply the ARM hunk.

> >>

> >> The only reason for the whole persistent region thing is to support

> >> GICv3 redistributors memory tables across kexec, for those GIC

> >> implementations where LPIs cannot be disabled once they have been

> >> enabled.

> >>

> >> There is no HW platform that combines 32bit cores and GICv3 (not to

> >> mention using EFI). The only existing "platform" is KVM/arm64, which

> >> doesn't suffer from the above problem (LPIs can be freely disabled in

> >> emulation). So the whole persistent region feature serves no purpose on

> >> 32bit ARM.

> >>

> >> The only issue with dropping this hunk is that the memory reservation

> >> feature is enabled on 32bit ARM the first place, which can easily be

> >> dealt with something along those lines:

> >

> > So, it was a waste of my time trying to understand what's going on here

> > with Ard's patch because it shouldn't be present on 32-bit ARM... Grr.

> >

> 

> Not really. I am trying really hard to do my part when it comes to

> keeping the maintenance level of the ARM architecture up. That means

> that all the improvements and enhancements that are implemented for

> EFI on arm64 are enabled on ARM as well, unless there are pressing

> reasons not to.

> 

> And even though this persistent reservation feature is only used by

> the GICv3 code at the moment, there may be other future uses as well,

> so I'd prefer not to special case ARM in this way.


Once you've come to some agreement on this, and you've looked at the
comment I've made (which leads me to regard your patch as a complete
non-starter for 32-bit ARM), I'll continue to look at it.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
diff mbox series

Patch

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ac7e08886863..e99f12eaf390 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1117,6 +1117,7 @@  void __init setup_arch(char **cmdline_p)
 	early_ioremap_reset();
 
 	paging_init(mdesc);
+	efi_apply_persistent_mem_reservations();
 	request_standard_resources(mdesc);
 
 	if (mdesc->restart)
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 953e316521fc..f4fc1e0544b7 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -313,6 +313,7 @@  void __init setup_arch(char **cmdline_p)
 	arm64_memblock_init();
 
 	paging_init();
+	efi_apply_persistent_mem_reservations();
 
 	acpi_table_upgrade();
 
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 249eb70691b0..55e4ea20bdc3 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -592,7 +592,11 @@  int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 
 		early_memunmap(tbl, sizeof(*tbl));
 	}
+	return 0;
+}
 
+int __init efi_apply_persistent_mem_reservations(void)
+{
 	if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
 		unsigned long prsv = efi.mem_reserve;
 
@@ -602,7 +606,7 @@  int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 			/* reserve the entry itself */
 			memblock_reserve(prsv, sizeof(*rsv));
 
-			rsv = early_memremap(prsv, sizeof(*rsv));
+			rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB);
 			if (rsv == NULL) {
 				pr_err("Could not map UEFI memreserve entry!\n");
 				return -ENOMEM;
@@ -612,7 +616,7 @@  int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 				memblock_reserve(rsv->base, rsv->size);
 
 			prsv = rsv->next;
-			early_memunmap(rsv, sizeof(*rsv));
+			memunmap(rsv);
 		}
 	}
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 845174e113ce..100ce4a4aff6 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1167,6 +1167,8 @@  static inline bool efi_enabled(int feature)
 extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
 
 extern bool efi_is_table_address(unsigned long phys_addr);
+
+extern int efi_apply_persistent_mem_reservations(void);
 #else
 static inline bool efi_enabled(int feature)
 {
@@ -1185,6 +1187,11 @@  static inline bool efi_is_table_address(unsigned long phys_addr)
 {
 	return false;
 }
+
+static inline int efi_apply_persistent_mem_reservations(void)
+{
+	return 0;
+}
 #endif
 
 extern int efi_status_to_err(efi_status_t status);