lkml.org 
[lkml]   [2016]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patches in this message
    /
    Date
    From
    SubjectRe: [PATCH 3.12 25/91] x86/setup: Extend low identity map to cover whole kernel range
    [ Adding Greg and Kamal ]

    On Wed, Jan 06, 2016 at 01:31:55PM +0000, Matt Fleming wrote:
    > On Wed, 06 Jan, at 11:24:55AM, Luis Henriques wrote:
    > > On Wed, Jan 06, 2016 at 11:00:31AM +0000, Matt Fleming wrote:
    > > > On Wed, 06 Jan, at 11:47:20AM, Paolo Bonzini wrote:
    > > > >
    > > > > Without testing the problematic scenario explicitly (32-bit UEFI
    > > > > kernel), I think this patch and 26/91 should not be backported to
    > > > > kernels that do not have 23a0d4e8fa6d.
    > > >
    > > > I tend to agree.
    > >
    > > I can see these 2 commits in kernels as old as 3.10 (which definitely do
    > > not include 23a0d4e8fa6d). Does this mean these should be reverted from
    > > stable kernels that already include these patches? Or would you rather
    > > recommend to backport 23a0d4e8fa6d?
    >
    > That depends on your appetite for risk ;-)
    >

    Heh, I guess stable kernels aren't really about appetite for risk :-)

    > 23a0d4e8fa6d does fix a legitimate bug, albeit one that no one seems
    > to have ever hit. Personally, I'd go for backporting 23a0d4e8fa6d.

    This commit doesn't seem to be too bad to backport. I'm attaching 2
    backports:

    - one is for the 3.16 stable kernel,
    - the other can be applied to 3.10, 3.12 and 3.13

    (For the other kernels, I believe 23a0d4e8fa6d will be a clean
    cherry-pick.)

    Cheers,
    --
    Luís
    From 6b58a852d51e7d1991d759c331bc276b2461c4c3 Mon Sep 17 00:00:00 2001
    From: Ingo Molnar <mingo@kernel.org>
    Date: Tue, 3 Mar 2015 07:34:33 +0100
    Subject: efi: Disable interrupts around EFI calls, not in the epilog/prolog
    calls

    commit 23a0d4e8fa6d3a1d7fb819f79bcc0a3739c30ba9 upstream.

    Tapasweni Pathak reported that we do a kmalloc() in efi_call_phys_prolog()
    on x86-64 while having interrupts disabled, which is a big no-no, as
    kmalloc() can sleep.

    Solve this by removing the irq disabling from the prolog/epilog calls
    around EFI calls: it's unnecessary, as in this stage we are single
    threaded in the boot thread, and we don't ever execute this from
    interrupt contexts.

    Reported-by: Tapasweni Pathak <tapaswenipathak@gmail.com>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Matt Fleming <matt.fleming@intel.com>
    [ luis: backported to 3.10: adjusted context ]
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/x86/platform/efi/efi.c | 7 +++++++
    arch/x86/platform/efi/efi_32.c | 11 +++--------
    arch/x86/platform/efi/efi_64.c | 3 ---
    3 files changed, 10 insertions(+), 11 deletions(-)

    diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
    index 6033be9ff81a..3c8bffdc71c8 100644
    --- a/arch/x86/platform/efi/efi.c
    +++ b/arch/x86/platform/efi/efi.c
    @@ -250,12 +250,19 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
    efi_memory_desc_t *virtual_map)
    {
    efi_status_t status;
    + unsigned long flags;

    efi_call_phys_prelog();
    +
    + /* Disable interrupts around EFI calls: */
    + local_irq_save(flags);
    status = efi_call_phys4(efi_phys.set_virtual_address_map,
    memory_map_size, descriptor_size,
    descriptor_version, virtual_map);
    + local_irq_restore(flags);
    +
    efi_call_phys_epilog();
    +
    return status;
    }

    diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
    index 40e446941dd7..bebbee05e331 100644
    --- a/arch/x86/platform/efi/efi_32.c
    +++ b/arch/x86/platform/efi/efi_32.c
    @@ -33,19 +33,16 @@

    /*
    * To make EFI call EFI runtime service in physical addressing mode we need
    - * prelog/epilog before/after the invocation to disable interrupt, to
    - * claim EFI runtime service handler exclusively and to duplicate a memory in
    - * low memory space say 0 - 3G.
    + * prolog/epilog before/after the invocation to claim the EFI runtime service
    + * handler exclusively and to duplicate a memory mapping in low memory space,
    + * say 0 - 3G.
    */

    -static unsigned long efi_rt_eflags;

    void efi_call_phys_prelog(void)
    {
    struct desc_ptr gdt_descr;

    - local_irq_save(efi_rt_eflags);
    -
    load_cr3(initial_page_table);
    __flush_tlb_all();

    @@ -64,6 +61,4 @@ void efi_call_phys_epilog(void)

    load_cr3(swapper_pg_dir);
    __flush_tlb_all();
    -
    - local_irq_restore(efi_rt_eflags);
    }
    diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
    index 39a0e7f1f0a3..2f6c1a9734c8 100644
    --- a/arch/x86/platform/efi/efi_64.c
    +++ b/arch/x86/platform/efi/efi_64.c
    @@ -40,7 +40,6 @@
    #include <asm/fixmap.h>

    static pgd_t *save_pgd __initdata;
    -static unsigned long efi_flags __initdata;

    static void __init early_code_mapping_set_exec(int executable)
    {
    @@ -66,7 +65,6 @@ void __init efi_call_phys_prelog(void)
    int n_pgds;

    early_code_mapping_set_exec(1);
    - local_irq_save(efi_flags);

    n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
    save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
    @@ -90,7 +88,6 @@ void __init efi_call_phys_epilog(void)
    set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
    kfree(save_pgd);
    __flush_tlb_all();
    - local_irq_restore(efi_flags);
    early_code_mapping_set_exec(0);
    }
    From 466b891857a536af2a9b7ad058e1cc00b702a528 Mon Sep 17 00:00:00 2001
    From: Ingo Molnar <mingo@kernel.org>
    Date: Tue, 3 Mar 2015 07:34:33 +0100
    Subject: [PATCH] efi: Disable interrupts around EFI calls, not in the
    epilog/prolog calls

    commit 23a0d4e8fa6d3a1d7fb819f79bcc0a3739c30ba9 upstream.

    Tapasweni Pathak reported that we do a kmalloc() in efi_call_phys_prolog()
    on x86-64 while having interrupts disabled, which is a big no-no, as
    kmalloc() can sleep.

    Solve this by removing the irq disabling from the prolog/epilog calls
    around EFI calls: it's unnecessary, as in this stage we are single
    threaded in the boot thread, and we don't ever execute this from
    interrupt contexts.

    Reported-by: Tapasweni Pathak <tapaswenipathak@gmail.com>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Matt Fleming <matt.fleming@intel.com>
    [ luis: backported to 3.16: adjusted context ]
    Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
    ---
    arch/x86/platform/efi/efi.c | 7 +++++++
    arch/x86/platform/efi/efi_32.c | 11 +++--------
    arch/x86/platform/efi/efi_64.c | 3 ---
    3 files changed, 10 insertions(+), 11 deletions(-)

    diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
    index 5bbb477f5c2a..09c8ac286cd5 100644
    --- a/arch/x86/platform/efi/efi.c
    +++ b/arch/x86/platform/efi/efi.c
    @@ -236,12 +236,19 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
    efi_memory_desc_t *virtual_map)
    {
    efi_status_t status;
    + unsigned long flags;

    efi_call_phys_prelog();
    +
    + /* Disable interrupts around EFI calls: */
    + local_irq_save(flags);
    status = efi_call_phys(efi_phys.set_virtual_address_map,
    memory_map_size, descriptor_size,
    descriptor_version, virtual_map);
    + local_irq_restore(flags);
    +
    efi_call_phys_epilog();
    +
    return status;
    }

    diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
    index 9ee3491e31fb..be4e7eb41674 100644
    --- a/arch/x86/platform/efi/efi_32.c
    +++ b/arch/x86/platform/efi/efi_32.c
    @@ -33,11 +33,10 @@

    /*
    * To make EFI call EFI runtime service in physical addressing mode we need
    - * prelog/epilog before/after the invocation to disable interrupt, to
    - * claim EFI runtime service handler exclusively and to duplicate a memory in
    - * low memory space say 0 - 3G.
    + * prolog/epilog before/after the invocation to claim the EFI runtime service
    + * handler exclusively and to duplicate a memory mapping in low memory space,
    + * say 0 - 3G.
    */
    -static unsigned long efi_rt_eflags;

    void efi_sync_low_kernel_mappings(void) {}
    void __init efi_dump_pagetable(void) {}
    @@ -59,8 +58,6 @@ void efi_call_phys_prelog(void)
    {
    struct desc_ptr gdt_descr;

    - local_irq_save(efi_rt_eflags);
    -
    load_cr3(initial_page_table);
    __flush_tlb_all();

    @@ -79,8 +76,6 @@ void efi_call_phys_epilog(void)

    load_cr3(swapper_pg_dir);
    __flush_tlb_all();
    -
    - local_irq_restore(efi_rt_eflags);
    }

    void __init efi_runtime_mkexec(void)
    diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
    index 290d397e1dd9..8139b4858403 100644
    --- a/arch/x86/platform/efi/efi_64.c
    +++ b/arch/x86/platform/efi/efi_64.c
    @@ -42,7 +42,6 @@
    #include <asm/time.h>

    static pgd_t *save_pgd __initdata;
    -static unsigned long efi_flags __initdata;

    /*
    * We allocate runtime services regions bottom-up, starting from -4G, i.e.
    @@ -89,7 +88,6 @@ void __init efi_call_phys_prelog(void)
    return;

    early_code_mapping_set_exec(1);
    - local_irq_save(efi_flags);

    n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
    save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
    @@ -117,7 +115,6 @@ void __init efi_call_phys_epilog(void)
    set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
    kfree(save_pgd);
    __flush_tlb_all();
    - local_irq_restore(efi_flags);
    early_code_mapping_set_exec(0);
    }
    \
     
     \ /
      Last update: 2016-01-06 15:41    [W:4.268 / U:0.328 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site