All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chintan Pandya <cpandya@codeaurora.org>
To: catalin.marinas@arm.com, will.deacon@arm.com, arnd@arndb.de
Cc: mark.rutland@arm.com, ard.biesheuvel@linaro.org,
	marc.zyngier@arm.com, james.morse@arm.com,
	kristina.martsenko@arm.com, takahiro.akashi@linaro.org,
	gregkh@linuxfoundation.org, tglx@linutronix.de,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
	akpm@linux-foundation.org, toshi.kani@hpe.com,
	Chintan Pandya <cpandya@codeaurora.org>
Subject: [PATCH v1 0/4] Fix issues with huge mapping in ioremap
Date: Wed, 14 Mar 2018 14:18:21 +0530	[thread overview]
Message-ID: <1521017305-28518-1-git-send-email-cpandya@codeaurora.org> (raw)

Note: I was working on these patches for quite sometime
and realized that Toshi Kani has shared some patches
addressing the same isssue with subject
"[PATCH 0/2] fix memory leak / panic in ioremap huge pages".
I've taken slightly different approach here, so sending
to the list, finally.

This patch series attempts to fix the issue described in
this discussion: https://lkml.org/lkml/2017/12/23/3

In summary, CONFIG_HAVE_ARCH_HUGE_VMAP has 2 issues
observed on ARM64

 1. Stale TLB entries
 2. Page table leaks

Will Deacon has by-passed huge mapping for ARM64
until these issues are fixed properly.

I've tested these patches on ARM64 based SDM845
with 4.9 kernel. Hanjun Guo <hanjun.guo@linaro.org>
shared test-case to reproduce this issue in
https://patchwork.kernel.org/patch/10134581/

However, I had no luck reproducing this issue with
exactly this test. I added some more code to reproduce
and here is my test which surfaces this issue in some
five hours of testing.

Test Code:

#define pr_fmt(fmt)     "IOREMAP_TEST: " fmt

#include <linux/console.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include <linux/io.h>
#include <linux/kthread.h>

static int io_remap_test(void *arg)
{
       phys_addr_t phy_addr_1 = 0x98000000;
       unsigned long block_size = 0x200000;
       unsigned long total_size = 0x400000;
       unsigned long va_addr_3;
       unsigned long va_addr_4;

       struct vm_struct *area;

       /*
        * run this test for 10 hours
        */
       u32 times_ms = 10 * 60 * 60 * 1000;
       unsigned long timeout = jiffies + msecs_to_jiffies(times_ms);
       int rand_type;
       int rand_value;
       u32 mem_size;
       int i;

       area = get_vm_area(total_size, VM_IOREMAP);
       va_addr_3 = (unsigned long)area->addr;
       va_addr_4 = va_addr_3 + block_size;
       pr_err("Virtual area %lx -- %lx\n", va_addr_3, va_addr_3 + total_size);

       ioremap_page_range(va_addr_3, va_addr_3 + block_size, phy_addr_1, __pgprot(PROT_DEVICE_nGnRE));
       pr_err("My tests will run now 2\n");
       do {
               get_random_bytes(&rand_value, sizeof(u32));

               rand_type = rand_value % 6;
               switch (rand_type) {
               case 0:
                       mem_size = 0x1000;
                       break;
               case 1:
                       mem_size = 0x8000;
                       break;
               case 2:
                       mem_size = 0x200000;
                       break;
               case 3:
                       mem_size = 0x30000;
                       break;
               case 4:
                       mem_size = 0x10000;
                       break;
               case 5:
                       mem_size = 0x40000;
                       break;
               default:
                       mem_size = 0x4000;
                       break;
               }

               /*
                * Prompt TLB to speculatively pre-fetch
                */
               readq(va_addr_3 + block_size - 0x20);
               readq(va_addr_3 + block_size - 0x18);
               readq(va_addr_3 + block_size - 0x10);
               readq(va_addr_3 + block_size - 0x8);

               ioremap_page_range(va_addr_4, va_addr_4 + mem_size, phy_addr_1, __pgprot(PROT_DEVICE_nGnRE));

               if (mem_size >= 0x200000 && !(rand_value%10000)) {
                       schedule();
                       pr_err("possible error case\n");
               }

               /*
                * Make CPU aware about our access pattern
                * Also, these accesses should lead to crash
                */
               for (i = 0; i < 5; i++ ) {
                       readq(va_addr_3 + block_size - 0x20);
                       readq(va_addr_3 + block_size - 0x18);
                       readq(va_addr_3 + block_size - 0x10);
                       readq(va_addr_3 + block_size - 0x8);
                       // Crash is expected here  
                       readq(va_addr_4);
                       readq(va_addr_4 + 0x8);
                       readq(va_addr_4 + 0x10);
                       readq(va_addr_4 + 0x18);
                       readq(va_addr_4 + 0x20);
               }

               unmap_kernel_range(va_addr_4, mem_size);
       } while (time_before(jiffies, timeout));

       pr_err("my tests ended now\n");
       return 0;
}

static int __init ioremap_testing_init(void)
{
       struct task_struct *t;
       pr_err("my tests will run now 1\n");

       t = kthread_create(&io_remap_test, NULL, "ioremap-testing");
       /*
        * Do this so that we can run this thread on GOLD cores
        */
       kthread_bind(t, 6);
       wake_up_process(t);
       return 0;
}
late_initcall(ioremap_testing_init);


Chintan Pandya (4):
  asm/tlbflush: Add flush_tlb_pgtable() for ARM64
  ioremap: Invalidate TLB after huge mappings
  arm64: Fix the page leak in pud/pmd_set_huge
  Revert "arm64: Enforce BBM for huge IO/VMAP mappings"

 arch/arm64/include/asm/tlbflush.h |  5 +++++
 arch/arm64/mm/mmu.c               | 17 ++++++++---------
 include/asm-generic/tlb.h         |  6 ++++++
 lib/ioremap.c                     |  9 +++++++--
 4 files changed, 26 insertions(+), 11 deletions(-)

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

WARNING: multiple messages have this Message-ID (diff)
From: cpandya@codeaurora.org (Chintan Pandya)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v1 0/4] Fix issues with huge mapping in ioremap
Date: Wed, 14 Mar 2018 14:18:21 +0530	[thread overview]
Message-ID: <1521017305-28518-1-git-send-email-cpandya@codeaurora.org> (raw)

Note: I was working on these patches for quite sometime
and realized that Toshi Kani has shared some patches
addressing the same isssue with subject
"[PATCH 0/2] fix memory leak / panic in ioremap huge pages".
I've taken slightly different approach here, so sending
to the list, finally.

This patch series attempts to fix the issue described in
this discussion: https://lkml.org/lkml/2017/12/23/3

In summary, CONFIG_HAVE_ARCH_HUGE_VMAP has 2 issues
observed on ARM64

 1. Stale TLB entries
 2. Page table leaks

Will Deacon has by-passed huge mapping for ARM64
until these issues are fixed properly.

I've tested these patches on ARM64 based SDM845
with 4.9 kernel. Hanjun Guo <hanjun.guo@linaro.org>
shared test-case to reproduce this issue in
https://patchwork.kernel.org/patch/10134581/

However, I had no luck reproducing this issue with
exactly this test. I added some more code to reproduce
and here is my test which surfaces this issue in some
five hours of testing.

Test Code:

#define pr_fmt(fmt)     "IOREMAP_TEST: " fmt

#include <linux/console.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include <linux/io.h>
#include <linux/kthread.h>

static int io_remap_test(void *arg)
{
       phys_addr_t phy_addr_1 = 0x98000000;
       unsigned long block_size = 0x200000;
       unsigned long total_size = 0x400000;
       unsigned long va_addr_3;
       unsigned long va_addr_4;

       struct vm_struct *area;

       /*
        * run this test for 10 hours
        */
       u32 times_ms = 10 * 60 * 60 * 1000;
       unsigned long timeout = jiffies + msecs_to_jiffies(times_ms);
       int rand_type;
       int rand_value;
       u32 mem_size;
       int i;

       area = get_vm_area(total_size, VM_IOREMAP);
       va_addr_3 = (unsigned long)area->addr;
       va_addr_4 = va_addr_3 + block_size;
       pr_err("Virtual area %lx -- %lx\n", va_addr_3, va_addr_3 + total_size);

       ioremap_page_range(va_addr_3, va_addr_3 + block_size, phy_addr_1, __pgprot(PROT_DEVICE_nGnRE));
       pr_err("My tests will run now 2\n");
       do {
               get_random_bytes(&rand_value, sizeof(u32));

               rand_type = rand_value % 6;
               switch (rand_type) {
               case 0:
                       mem_size = 0x1000;
                       break;
               case 1:
                       mem_size = 0x8000;
                       break;
               case 2:
                       mem_size = 0x200000;
                       break;
               case 3:
                       mem_size = 0x30000;
                       break;
               case 4:
                       mem_size = 0x10000;
                       break;
               case 5:
                       mem_size = 0x40000;
                       break;
               default:
                       mem_size = 0x4000;
                       break;
               }

               /*
                * Prompt TLB to speculatively pre-fetch
                */
               readq(va_addr_3 + block_size - 0x20);
               readq(va_addr_3 + block_size - 0x18);
               readq(va_addr_3 + block_size - 0x10);
               readq(va_addr_3 + block_size - 0x8);

               ioremap_page_range(va_addr_4, va_addr_4 + mem_size, phy_addr_1, __pgprot(PROT_DEVICE_nGnRE));

               if (mem_size >= 0x200000 && !(rand_value%10000)) {
                       schedule();
                       pr_err("possible error case\n");
               }

               /*
                * Make CPU aware about our access pattern
                * Also, these accesses should lead to crash
                */
               for (i = 0; i < 5; i++ ) {
                       readq(va_addr_3 + block_size - 0x20);
                       readq(va_addr_3 + block_size - 0x18);
                       readq(va_addr_3 + block_size - 0x10);
                       readq(va_addr_3 + block_size - 0x8);
                       // Crash is expected here  
                       readq(va_addr_4);
                       readq(va_addr_4 + 0x8);
                       readq(va_addr_4 + 0x10);
                       readq(va_addr_4 + 0x18);
                       readq(va_addr_4 + 0x20);
               }

               unmap_kernel_range(va_addr_4, mem_size);
       } while (time_before(jiffies, timeout));

       pr_err("my tests ended now\n");
       return 0;
}

static int __init ioremap_testing_init(void)
{
       struct task_struct *t;
       pr_err("my tests will run now 1\n");

       t = kthread_create(&io_remap_test, NULL, "ioremap-testing");
       /*
        * Do this so that we can run this thread on GOLD cores
        */
       kthread_bind(t, 6);
       wake_up_process(t);
       return 0;
}
late_initcall(ioremap_testing_init);


Chintan Pandya (4):
  asm/tlbflush: Add flush_tlb_pgtable() for ARM64
  ioremap: Invalidate TLB after huge mappings
  arm64: Fix the page leak in pud/pmd_set_huge
  Revert "arm64: Enforce BBM for huge IO/VMAP mappings"

 arch/arm64/include/asm/tlbflush.h |  5 +++++
 arch/arm64/mm/mmu.c               | 17 ++++++++---------
 include/asm-generic/tlb.h         |  6 ++++++
 lib/ioremap.c                     |  9 +++++++--
 4 files changed, 26 insertions(+), 11 deletions(-)

-- 
Qualcomm India Private Limited, on behalf of Qualcomm Innovation
Center, Inc., is a member of Code Aurora Forum, a Linux Foundation
Collaborative Project

             reply	other threads:[~2018-03-14  8:48 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-14  8:48 Chintan Pandya [this message]
2018-03-14  8:48 ` [PATCH v1 0/4] Fix issues with huge mapping in ioremap Chintan Pandya
2018-03-14  8:48 ` [PATCH v1 1/4] asm/tlbflush: Add flush_tlb_pgtable() for ARM64 Chintan Pandya
2018-03-14  8:48   ` Chintan Pandya
2018-03-16  8:26   ` kbuild test robot
2018-03-16  8:26     ` kbuild test robot
2018-03-16  8:26     ` kbuild test robot
2018-03-16  8:26     ` kbuild test robot
2018-03-14  8:48 ` [PATCH v1 2/4] ioremap: Invalidate TLB after huge mappings Chintan Pandya
2018-03-14  8:48   ` Chintan Pandya
2018-03-14 10:48   ` Mark Rutland
2018-03-14 10:48     ` Mark Rutland
2018-03-14 11:20     ` Chintan Pandya
2018-03-14 11:20       ` Chintan Pandya
2018-03-14 11:48       ` Mark Rutland
2018-03-14 11:48         ` Mark Rutland
2018-03-14  8:48 ` [PATCH v1 3/4] arm64: Fix the page leak in pud/pmd_set_huge Chintan Pandya
2018-03-14  8:48   ` Chintan Pandya
2018-03-14 10:35   ` Marc Zyngier
2018-03-14 10:35     ` Marc Zyngier
2018-03-14 10:53   ` Mark Rutland
2018-03-14 10:53     ` Mark Rutland
2018-03-14 11:27     ` Chintan Pandya
2018-03-14 11:27       ` Chintan Pandya
2018-03-14 11:50       ` Mark Rutland
2018-03-14 11:50         ` Mark Rutland
2018-03-16 14:50   ` kbuild test robot
2018-03-16 14:50     ` kbuild test robot
2018-03-16 14:50     ` kbuild test robot
2018-03-16 14:50     ` kbuild test robot
2018-03-14  8:48 ` [PATCH v1 4/4] Revert "arm64: Enforce BBM for huge IO/VMAP mappings" Chintan Pandya
2018-03-14  8:48   ` Chintan Pandya
2018-03-14 10:46   ` Marc Zyngier
2018-03-14 10:46     ` Marc Zyngier
2018-03-14 11:32     ` Chintan Pandya
2018-03-14 11:32       ` Chintan Pandya
2018-03-14 14:38 ` [PATCH v1 0/4] Fix issues with huge mapping in ioremap Kani, Toshi
2018-03-14 14:38   ` Kani, Toshi
2018-03-15  7:17   ` Chintan Pandya
2018-03-15  7:17     ` Chintan Pandya
2018-03-15 14:38     ` Kani, Toshi
2018-03-15 14:38       ` Kani, Toshi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1521017305-28518-1-git-send-email-cpandya@codeaurora.org \
    --to=cpandya@codeaurora.org \
    --cc=akpm@linux-foundation.org \
    --cc=ard.biesheuvel@linaro.org \
    --cc=arnd@arndb.de \
    --cc=catalin.marinas@arm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=james.morse@arm.com \
    --cc=kristina.martsenko@arm.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=takahiro.akashi@linaro.org \
    --cc=tglx@linutronix.de \
    --cc=toshi.kani@hpe.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.