From: Michal Hocko <mhocko@kernel.org>
To: zijun_hu <zijun_hu@zoho.com>
Cc: zijun_hu@htc.com, Andrew Morton <akpm@linux-foundation.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org, tj@kernel.org,
mingo@kernel.org, rientjes@google.com, iamjoonsoo.kim@lge.com,
mgorman@techsingularity.net
Subject: Re: [PATCH 1/1] lib/ioremap.c: avoid endless loop under ioremapping page unaligned ranges
Date: Fri, 23 Sep 2016 10:45:51 +0200 [thread overview]
Message-ID: <20160923084551.GG4478@dhcp22.suse.cz> (raw)
In-Reply-To: <35661a34-c3e0-0ec2-b58f-ee59bef4e4d4@zoho.com>
On Thu 22-09-16 23:13:17, zijun_hu wrote:
> On 2016/9/22 20:47, Michal Hocko wrote:
> > On Wed 21-09-16 12:19:53, zijun_hu wrote:
> >> From: zijun_hu <zijun_hu@htc.com>
> >>
> >> endless loop maybe happen if either of parameter addr and end is not
> >> page aligned for kernel API function ioremap_page_range()
> >
> > Does this happen in practise or this you found it by reading the code?
> >
> i found it by reading the code, this is a kernel API function and there
> are no enough hint for parameter requirements, so any parameters
> combination maybe be used by user, moreover, it seems appropriate for
> many bad parameter combination, for example, provided PMD_SIZE=2M and
> PAGE_SIZE=4K, 0x00 is used for aligned very well address
> a user maybe want to map virtual range[0x1ff800, 0x200800) to physical address
> 0x300800, it will cause endless loop
Well, we are relying on the kernel to do the sane thing otherwise we
would be screwed anyway. If this can be triggered by a userspace then it
would be a different story. Just look at how we are doing mmap, we
sanitize the page alignment at the high level and the lower level
functions just assume sane values.
> >> in order to fix this issue and alert improper range parameters to user
> >> WARN_ON() checkup and rounding down range lower boundary are performed
> >> firstly, loop end condition within ioremap_pte_range() is optimized due
> >> to lack of relevant macro pte_addr_end()
> >>
> >> Signed-off-by: zijun_hu <zijun_hu@htc.com>
> >> ---
> >> lib/ioremap.c | 4 +++-
> >> 1 file changed, 3 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/lib/ioremap.c b/lib/ioremap.c
> >> index 86c8911..911bdca 100644
> >> --- a/lib/ioremap.c
> >> +++ b/lib/ioremap.c
> >> @@ -64,7 +64,7 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
> >> BUG_ON(!pte_none(*pte));
> >> set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
> >> pfn++;
> >> - } while (pte++, addr += PAGE_SIZE, addr != end);
> >> + } while (pte++, addr += PAGE_SIZE, addr < end && addr >= PAGE_SIZE);
> >> return 0;
> >> }
> >
> > Ble, this just overcomplicate things. Can we just make sure that the
> > proper alignment is done in ioremap_page_range which is the only caller
> > of this (and add VM_BUG_ON in ioremap_pud_range to make sure no new
> > caller will forget about that).
> >
> this complicate express is used to avoid addr overflow, consider map
> virtual rang [0xffe00800, 0xfffff800) for 32bit machine
> actually, my previous approach is just like that you pointed mailed at 20/09
> as below, besides, i apply my previous approach for mm/vmalloc.c and
> npiggin@gmail.com have "For API functions perhaps it's reasonable" comments
> i don't tell which is better
>
> diff --git a/lib/ioremap.c b/lib/ioremap.c
> --- a/lib/ioremap.c
> +++ b/lib/ioremap.c
> @@ -64,7 +64,7 @@ static int ioremap_pte_range(pmd_t *pmd, unsigned long addr,
> BUG_ON(!pte_none(*pte));
> set_pte_at(&init_mm, addr, pte, pfn_pte(pfn, prot));
> pfn++;
> - } while (pte++, addr += PAGE_SIZE, addr != end);
> + } while (pte++, addr += PAGE_SIZE, addr < end);
> return 0;
> }
yes this looks good to me
>
> @@ -129,6 +129,7 @@ int ioremap_page_range(unsigned long addr,
> int err;
>
> BUG_ON(addr >= end);
> + BUG_ON(!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(end));
Well, BUG_ON is rather harsh for something that would be trivially
fixable.
>
> start = addr;
> phys_addr -= addr;
>
> >>
> >> @@ -129,7 +129,9 @@ int ioremap_page_range(unsigned long addr,
> >> int err;
> >>
> >> BUG_ON(addr >= end);
> >> + WARN_ON(!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(end));
> >
> > maybe WARN_ON_ONCE would be sufficient to prevent from swamping logs if
> > something just happens to do this too often in some pathological path.
> >
> if WARN_ON_ONCE is used, the later bad ranges for many other purposes can't
> be alerted, and ioremap_page_range() can map large enough ranges so not too many
> calls happens for a purpose
> >>
> >> + addr = round_down(addr, PAGE_SIZE);
> >
> > end = round_up(end, PAGE_SIZE);
> >
> > wouldn't work?
> >
> no, it don't work for many special case
> for example, provided PMD_SIZE=2M
> mapping [0x1f8800, 0x208800) virtual range will be split to two ranges
> [0x1f8800, 0x200000) and [0x200000,0x208800) and map them separately
> the first range will cause dead loop
I am not sure I see your point. How can we deadlock if _both_ addresses
get aligned to the page boundary and how does PMD_SIZE make any
difference.
--
Michal Hocko
SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2016-09-23 8:45 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-21 4:19 zijun_hu
2016-09-22 12:47 ` Michal Hocko
2016-09-22 15:13 ` zijun_hu
2016-09-23 8:45 ` Michal Hocko [this message]
2016-09-23 12:29 ` zijun_hu
2016-09-23 12:42 ` Michal Hocko
2016-09-23 13:00 ` zijun_hu
2016-09-23 13:33 ` Michal Hocko
2016-09-23 14:14 ` zijun_hu
2016-09-23 14:27 ` Michal Hocko
2016-09-23 14:58 ` zijun_hu
2016-09-23 5:53 ` [PATCH v2 " zijun_hu
2016-09-23 14:42 ` [PATCH " Tejun Heo
2016-09-23 15:41 ` zijun_hu
2016-09-23 16:23 ` Tejun Heo
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=20160923084551.GG4478@dhcp22.suse.cz \
--to=mhocko@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=iamjoonsoo.kim@lge.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mgorman@techsingularity.net \
--cc=mingo@kernel.org \
--cc=rientjes@google.com \
--cc=tj@kernel.org \
--cc=zijun_hu@htc.com \
--cc=zijun_hu@zoho.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox