lkml.org 
[lkml]   [2020]   [Jan]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 74/74] perf/x86/intel/bts: Fix the use of page_private()
    Date
    From: Alexander Shishkin <alexander.shishkin@linux.intel.com>

    [ Upstream commit ff61541cc6c1962957758ba433c574b76f588d23 ]

    Commit

    8062382c8dbe2 ("perf/x86/intel/bts: Add BTS PMU driver")

    brought in a warning with the BTS buffer initialization
    that is easily tripped with (assuming KPTI is disabled):

    instantly throwing:

    > ------------[ cut here ]------------
    > WARNING: CPU: 2 PID: 326 at arch/x86/events/intel/bts.c:86 bts_buffer_setup_aux+0x117/0x3d0
    > Modules linked in:
    > CPU: 2 PID: 326 Comm: perf Not tainted 5.4.0-rc8-00291-gceb9e77324fa #904
    > RIP: 0010:bts_buffer_setup_aux+0x117/0x3d0
    > Call Trace:
    > rb_alloc_aux+0x339/0x550
    > perf_mmap+0x607/0xc70
    > mmap_region+0x76b/0xbd0
    ...

    It appears to assume (for lost raisins) that PagePrivate() is set,
    while later it actually tests for PagePrivate() before using
    page_private().

    Make it consistent and always check PagePrivate() before using
    page_private().

    Fixes: 8062382c8dbe2 ("perf/x86/intel/bts: Add BTS PMU driver")
    Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Vince Weaver <vincent.weaver@maine.edu>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Link: https://lkml.kernel.org/r/20191205142853.28894-2-alexander.shishkin@linux.intel.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/x86/events/intel/bts.c | 16 +++++++++++-----
    1 file changed, 11 insertions(+), 5 deletions(-)

    diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
    index 24ffa1e88cf9..4d3399405d06 100644
    --- a/arch/x86/events/intel/bts.c
    +++ b/arch/x86/events/intel/bts.c
    @@ -71,9 +71,17 @@ struct bts_buffer {

    static struct pmu bts_pmu;

    +static int buf_nr_pages(struct page *page)
    +{
    + if (!PagePrivate(page))
    + return 1;
    +
    + return 1 << page_private(page);
    +}
    +
    static size_t buf_size(struct page *page)
    {
    - return 1 << (PAGE_SHIFT + page_private(page));
    + return buf_nr_pages(page) * PAGE_SIZE;
    }

    static void *
    @@ -89,9 +97,7 @@ bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
    /* count all the high order buffers */
    for (pg = 0, nbuf = 0; pg < nr_pages;) {
    page = virt_to_page(pages[pg]);
    - if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
    - return NULL;
    - pg += 1 << page_private(page);
    + pg += buf_nr_pages(page);
    nbuf++;
    }

    @@ -115,7 +121,7 @@ bts_buffer_setup_aux(int cpu, void **pages, int nr_pages, bool overwrite)
    unsigned int __nr_pages;

    page = virt_to_page(pages[pg]);
    - __nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
    + __nr_pages = buf_nr_pages(page);
    buf->buf[nbuf].page = page;
    buf->buf[nbuf].offset = offset;
    buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-07 22:40    [W:4.044 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site