lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.8 359/633] powerpc/pseries/svm: Allocate SWIOTLB buffer anywhere in memory
    Date
    From: Thiago Jung Bauermann <bauerman@linux.ibm.com>

    [ Upstream commit eae9eec476d13fad9af6da1f44a054ee02b7b161 ]

    POWER secure guests (i.e., guests which use the Protected Execution
    Facility) need to use SWIOTLB to be able to do I/O with the
    hypervisor, but they don't need the SWIOTLB memory to be in low
    addresses since the hypervisor doesn't have any addressing limitation.

    This solves a SWIOTLB initialization problem we are seeing in secure
    guests with 128 GB of RAM: they are configured with 4 GB of
    crashkernel reserved memory, which leaves no space for SWIOTLB in low
    addresses.

    To do this, we use mostly the same code as swiotlb_init(), but
    allocate the buffer using memblock_alloc() instead of
    memblock_alloc_low().

    Fixes: 2efbc58f157a ("powerpc/pseries/svm: Force SWIOTLB for secure guests")
    Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
    Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20200818221126.391073-1-bauerman@linux.ibm.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/include/asm/svm.h | 4 ++++
    arch/powerpc/mm/mem.c | 6 +++++-
    arch/powerpc/platforms/pseries/svm.c | 26 ++++++++++++++++++++++++++
    3 files changed, 35 insertions(+), 1 deletion(-)

    diff --git a/arch/powerpc/include/asm/svm.h b/arch/powerpc/include/asm/svm.h
    index 85580b30aba48..7546402d796af 100644
    --- a/arch/powerpc/include/asm/svm.h
    +++ b/arch/powerpc/include/asm/svm.h
    @@ -15,6 +15,8 @@ static inline bool is_secure_guest(void)
    return mfmsr() & MSR_S;
    }

    +void __init svm_swiotlb_init(void);
    +
    void dtl_cache_ctor(void *addr);
    #define get_dtl_cache_ctor() (is_secure_guest() ? dtl_cache_ctor : NULL)

    @@ -25,6 +27,8 @@ static inline bool is_secure_guest(void)
    return false;
    }

    +static inline void svm_swiotlb_init(void) {}
    +
    #define get_dtl_cache_ctor() NULL

    #endif /* CONFIG_PPC_SVM */
    diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
    index c2c11eb8dcfca..0f21bcb16405a 100644
    --- a/arch/powerpc/mm/mem.c
    +++ b/arch/powerpc/mm/mem.c
    @@ -50,6 +50,7 @@
    #include <asm/swiotlb.h>
    #include <asm/rtas.h>
    #include <asm/kasan.h>
    +#include <asm/svm.h>

    #include <mm/mmu_decl.h>

    @@ -290,7 +291,10 @@ void __init mem_init(void)
    * back to to-down.
    */
    memblock_set_bottom_up(true);
    - swiotlb_init(0);
    + if (is_secure_guest())
    + svm_swiotlb_init();
    + else
    + swiotlb_init(0);
    #endif

    high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
    diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c
    index 40c0637203d5b..81085eb8f2255 100644
    --- a/arch/powerpc/platforms/pseries/svm.c
    +++ b/arch/powerpc/platforms/pseries/svm.c
    @@ -7,6 +7,7 @@
    */

    #include <linux/mm.h>
    +#include <linux/memblock.h>
    #include <asm/machdep.h>
    #include <asm/svm.h>
    #include <asm/swiotlb.h>
    @@ -34,6 +35,31 @@ static int __init init_svm(void)
    }
    machine_early_initcall(pseries, init_svm);

    +/*
    + * Initialize SWIOTLB. Essentially the same as swiotlb_init(), except that it
    + * can allocate the buffer anywhere in memory. Since the hypervisor doesn't have
    + * any addressing limitation, we don't need to allocate it in low addresses.
    + */
    +void __init svm_swiotlb_init(void)
    +{
    + unsigned char *vstart;
    + unsigned long bytes, io_tlb_nslabs;
    +
    + io_tlb_nslabs = (swiotlb_size_or_default() >> IO_TLB_SHIFT);
    + io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
    +
    + bytes = io_tlb_nslabs << IO_TLB_SHIFT;
    +
    + vstart = memblock_alloc(PAGE_ALIGN(bytes), PAGE_SIZE);
    + if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, false))
    + return;
    +
    + if (io_tlb_start)
    + memblock_free_early(io_tlb_start,
    + PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
    + panic("SVM: Cannot allocate SWIOTLB buffer");
    +}
    +
    int set_memory_encrypted(unsigned long addr, int numpages)
    {
    if (!PAGE_ALIGNED(addr))
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-10-27 16:10    [W:2.423 / U:0.116 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site