* Re: [PATCH 1/1] infiniband/mm: convert put_page() to put_user_page*()
From: Ira Weiny @ 2019-05-23 17:28 UTC (permalink / raw)
To: john.hubbard
Cc: Andrew Morton, linux-mm, Jason Gunthorpe, LKML, linux-rdma,
linux-fsdevel, John Hubbard, Doug Ledford, Mike Marciniszyn,
Dennis Dalessandro, Christian Benvenuti, Jan Kara,
Jason Gunthorpe
In-Reply-To: <20190523072537.31940-2-jhubbard@nvidia.com>
On Thu, May 23, 2019 at 12:25:37AM -0700, john.hubbard@gmail.com wrote:
> From: John Hubbard <jhubbard@nvidia.com>
>
> For infiniband code that retains pages via get_user_pages*(),
> release those pages via the new put_user_page(), or
> put_user_pages*(), instead of put_page()
>
> This is a tiny part of the second step of fixing the problem described
> in [1]. The steps are:
>
> 1) Provide put_user_page*() routines, intended to be used
> for releasing pages that were pinned via get_user_pages*().
>
> 2) Convert all of the call sites for get_user_pages*(), to
> invoke put_user_page*(), instead of put_page(). This involves dozens of
> call sites, and will take some time.
>
> 3) After (2) is complete, use get_user_pages*() and put_user_page*() to
> implement tracking of these pages. This tracking will be separate from
> the existing struct page refcounting.
>
> 4) Use the tracking and identification of these pages, to implement
> special handling (especially in writeback paths) when the pages are
> backed by a filesystem. Again, [1] provides details as to why that is
> desirable.
>
> [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()"
>
> Cc: Doug Ledford <dledford@redhat.com>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
> Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
> Cc: Christian Benvenuti <benve@cisco.com>
>
> Reviewed-by: Jan Kara <jack@suse.cz>
> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
> Acked-by: Jason Gunthorpe <jgg@mellanox.com>
> Tested-by: Ira Weiny <ira.weiny@intel.com>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
> ---
> drivers/infiniband/core/umem.c | 7 ++++---
> drivers/infiniband/core/umem_odp.c | 10 +++++-----
> drivers/infiniband/hw/hfi1/user_pages.c | 11 ++++-------
> drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++---
> drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++++-------
> drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +++---
> drivers/infiniband/hw/usnic/usnic_uiom.c | 7 ++++---
> 7 files changed, 27 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> index e7ea819fcb11..673f0d240b3e 100644
> --- a/drivers/infiniband/core/umem.c
> +++ b/drivers/infiniband/core/umem.c
> @@ -54,9 +54,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
>
> for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->sg_nents, 0) {
> page = sg_page_iter_page(&sg_iter);
> - if (!PageDirty(page) && umem->writable && dirty)
> - set_page_dirty_lock(page);
> - put_page(page);
> + if (umem->writable && dirty)
> + put_user_pages_dirty_lock(&page, 1);
> + else
> + put_user_page(page);
> }
>
> sg_free_table(&umem->sg_head);
> diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
> index f962b5bbfa40..17e46df3990a 100644
> --- a/drivers/infiniband/core/umem_odp.c
> +++ b/drivers/infiniband/core/umem_odp.c
> @@ -487,7 +487,7 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
> * The function returns -EFAULT if the DMA mapping operation fails. It returns
> * -EAGAIN if a concurrent invalidation prevents us from updating the page.
> *
> - * The page is released via put_page even if the operation failed. For
> + * The page is released via put_user_page even if the operation failed. For
> * on-demand pinning, the page is released whenever it isn't stored in the
> * umem.
> */
> @@ -536,7 +536,7 @@ static int ib_umem_odp_map_dma_single_page(
> }
>
> out:
> - put_page(page);
> + put_user_page(page);
>
> if (remove_existing_mapping) {
> ib_umem_notifier_start_account(umem_odp);
> @@ -659,7 +659,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
> ret = -EFAULT;
> break;
> }
> - put_page(local_page_list[j]);
> + put_user_page(local_page_list[j]);
> continue;
> }
>
> @@ -686,8 +686,8 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
> * ib_umem_odp_map_dma_single_page().
> */
> if (npages - (j + 1) > 0)
> - release_pages(&local_page_list[j+1],
> - npages - (j + 1));
> + put_user_pages(&local_page_list[j+1],
> + npages - (j + 1));
I don't know if we discussed this before but it looks like the use of
release_pages() was not entirely correct (or at least not necessary) here. So
I think this is ok.
As for testing, I have been running with this patch for a while but I don't
have ODP hardware so that testing would not cover this code path. So you can
add my:
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
> break;
> }
> }
> diff --git a/drivers/infiniband/hw/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c
> index 02eee8eff1db..b89a9b9aef7a 100644
> --- a/drivers/infiniband/hw/hfi1/user_pages.c
> +++ b/drivers/infiniband/hw/hfi1/user_pages.c
> @@ -118,13 +118,10 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np
> void hfi1_release_user_pages(struct mm_struct *mm, struct page **p,
> size_t npages, bool dirty)
> {
> - size_t i;
> -
> - for (i = 0; i < npages; i++) {
> - if (dirty)
> - set_page_dirty_lock(p[i]);
> - put_page(p[i]);
> - }
> + if (dirty)
> + put_user_pages_dirty_lock(p, npages);
> + else
> + put_user_pages(p, npages);
>
> if (mm) { /* during close after signal, mm can be NULL */
> atomic64_sub(npages, &mm->pinned_vm);
> diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
> index 8ff0e90d7564..edccfd6e178f 100644
> --- a/drivers/infiniband/hw/mthca/mthca_memfree.c
> +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
> @@ -482,7 +482,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
>
> ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
> if (ret < 0) {
> - put_page(pages[0]);
> + put_user_page(pages[0]);
> goto out;
> }
>
> @@ -490,7 +490,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
> mthca_uarc_virt(dev, uar, i));
> if (ret) {
> pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
> - put_page(sg_page(&db_tab->page[i].mem));
> + put_user_page(sg_page(&db_tab->page[i].mem));
> goto out;
> }
>
> @@ -556,7 +556,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
> if (db_tab->page[i].uvirt) {
> mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1);
> pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
> - put_page(sg_page(&db_tab->page[i].mem));
> + put_user_page(sg_page(&db_tab->page[i].mem));
> }
> }
>
> diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c
> index f712fb7fa82f..bfbfbb7e0ff4 100644
> --- a/drivers/infiniband/hw/qib/qib_user_pages.c
> +++ b/drivers/infiniband/hw/qib/qib_user_pages.c
> @@ -40,13 +40,10 @@
> static void __qib_release_user_pages(struct page **p, size_t num_pages,
> int dirty)
> {
> - size_t i;
> -
> - for (i = 0; i < num_pages; i++) {
> - if (dirty)
> - set_page_dirty_lock(p[i]);
> - put_page(p[i]);
> - }
> + if (dirty)
> + put_user_pages_dirty_lock(p, num_pages);
> + else
> + put_user_pages(p, num_pages);
> }
>
> /**
> diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c
> index 0c204776263f..ac5bdb02144f 100644
> --- a/drivers/infiniband/hw/qib/qib_user_sdma.c
> +++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
> @@ -317,7 +317,7 @@ static int qib_user_sdma_page_to_frags(const struct qib_devdata *dd,
> * the caller can ignore this page.
> */
> if (put) {
> - put_page(page);
> + put_user_page(page);
> } else {
> /* coalesce case */
> kunmap(page);
> @@ -631,7 +631,7 @@ static void qib_user_sdma_free_pkt_frag(struct device *dev,
> kunmap(pkt->addr[i].page);
>
> if (pkt->addr[i].put_page)
> - put_page(pkt->addr[i].page);
> + put_user_page(pkt->addr[i].page);
> else
> __free_page(pkt->addr[i].page);
> } else if (pkt->addr[i].kvaddr) {
> @@ -706,7 +706,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
> /* if error, return all pages not managed by pkt */
> free_pages:
> while (i < j)
> - put_page(pages[i++]);
> + put_user_page(pages[i++]);
>
> done:
> return ret;
> diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
> index e312f522a66d..0b0237d41613 100644
> --- a/drivers/infiniband/hw/usnic/usnic_uiom.c
> +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
> @@ -75,9 +75,10 @@ static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
> for_each_sg(chunk->page_list, sg, chunk->nents, i) {
> page = sg_page(sg);
> pa = sg_phys(sg);
> - if (!PageDirty(page) && dirty)
> - set_page_dirty_lock(page);
> - put_page(page);
> + if (dirty)
> + put_user_pages_dirty_lock(&page, 1);
> + else
> + put_user_page(page);
> usnic_dbg("pa: %pa\n", &pa);
> }
> kfree(chunk);
> --
> 2.21.0
>
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 17:00 UTC (permalink / raw)
To: enh
Cc: Kees Cook, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz,
Linux ARM, Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <CAJgzZoqX--Kd9=Kjpnfz-5cjVJ=TdsXM5dJM_EjLFKniVbny2w@mail.gmail.com>
On Thu, May 23, 2019 at 08:44:12AM -0700, enh wrote:
> On Thu, May 23, 2019 at 7:45 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Wed, May 22, 2019 at 01:47:36PM -0700, Kees Cook wrote:
> > > For userspace, how would a future binary choose TBI over MTE? If it's
> > > a library issue, we can't use an ELF bit, since the choice may be
> > > "late" after ELF load (this implies the need for a prctl().) If it's
> > > binary-only ("built with HWKASan") then an ELF bit seems sufficient.
> > > And without the marking, I'd expect the kernel to enforce MTE when
> > > there are high bits.
> >
> > The current plan is that a future binary issues a prctl(), after
> > checking the HWCAP_MTE bit (as I replied to Elliot, the MTE instructions
> > are not in the current NOP space). I'd expect this to be done by the
> > libc or dynamic loader under the assumption that the binaries it loads
> > do _not_ use the top pointer byte for anything else.
>
> yeah, it sounds like to support hwasan and MTE, the dynamic linker
> will need to not use either itself.
>
> > With hwasan compiled objects this gets more confusing (any ELF note
> > to identify them?).
>
> no, at the moment code that wants to know checks for the presence of
> __hwasan_init. (and bionic doesn't actually look at any ELF notes
> right now.) but we can always add something if we need to.
It's a userspace decision to make. In the kernel, we are proposing that
bionic calls a prctl() to enable MTE explicitly. It could first check
for the presence of __hwasan_init.
--
Catalin
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 16:57 UTC (permalink / raw)
To: Dave Martin
Cc: Jason Gunthorpe, Mark Rutland, kvm, Christian Koenig,
Szabolcs Nagy, Will Deacon, dri-devel, linux-mm, Lee Smith,
linux-kselftest, Vincenzo Frascino, Jacob Bramley,
Leon Romanovsky, linux-rdma, amd-gfx, linux-arm-kernel,
Evgeniy Stepanov, linux-media, Kees Cook, Ruben Ayrapetyan,
Andrey Konovalov, Kevin Brodsky
In-Reply-To: <20190523104256.GX28398@e103592.cambridge.arm.com>
On Thu, May 23, 2019 at 11:42:57AM +0100, Dave P Martin wrote:
> On Wed, May 22, 2019 at 09:20:52PM -0300, Jason Gunthorpe wrote:
> > On Wed, May 22, 2019 at 02:49:28PM +0100, Dave Martin wrote:
> > > If multiple people will care about this, perhaps we should try to
> > > annotate types more explicitly in SYSCALL_DEFINEx() and ABI data
> > > structures.
> > >
> > > For example, we could have a couple of mutually exclusive modifiers
> > >
> > > T __object *
> > > T __vaddr * (or U __vaddr)
> > >
> > > In the first case the pointer points to an object (in the C sense)
> > > that the call may dereference but not use for any other purpose.
> >
> > How would you use these two differently?
> >
> > So far the kernel has worked that __user should tag any pointer that
> > is from userspace and then you can't do anything with it until you
> > transform it into a kernel something
>
> Ultimately it would be good to disallow casting __object pointers execpt
> to compatible __object pointer types, and to make get_user etc. demand
> __object.
>
> __vaddr pointers / addresses would be freely castable, but not to
> __object and so would not be dereferenceable even indirectly.
I think it gets too complicated and there are ambiguous cases that we
may not be able to distinguish. For example copy_from_user() may be used
to copy a user data structure into the kernel, hence __object would
work, while the same function may be used to copy opaque data to a file,
so __vaddr may be a better option (unless I misunderstood your
proposal).
We currently have T __user * and I think it's a good starting point. The
prior attempt [1] was shut down because it was just hiding the cast
using __force. We'd need to work through those cases again and rather
start changing the function prototypes to avoid unnecessary casting in
the callers (e.g. get_user_pages(void __user *) or come up with a new
type) while changing the explicit casting to a macro where it needs to
be obvious that we are converting a user pointer, potentially typed
(tagged), to an untyped address range. We may need a user_ptr_to_ulong()
macro or similar (it seems that we have a u64_to_user_ptr, wasn't aware
of it).
It may actually not be far from what you suggested but I'd keep the
current T __user * to denote possible dereference.
[1] https://lore.kernel.org/lkml/5d54526e5ff2e5ad63d0dfdd9ab17cf359afa4f2.1535629099.git.andreyknvl@google.com/
--
Catalin
^ permalink raw reply
* Re: [RFC][PATCH] kernel.h: Add generic roundup_64() macro
From: Linus Torvalds @ 2019-05-23 16:51 UTC (permalink / raw)
To: Steven Rostedt
Cc: Leon Romanovsky, Darrick J. Wong, David Airlie,
nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, LKML, dri-devel,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, Jason Gunthorpe, Doug Ledford,
Ben Skeggs, Daniel Vetter, Andrew Morton, linux-rdma
In-Reply-To: <20190523112740.7167aba4-f9ZlEuEWxVcJvu8Pb33WZ0EMvNT87kid@public.gmane.org>
On Thu, May 23, 2019 at 8:27 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> I haven't yet tested this, but what about something like the following:
So that at least handles the constant case that the normal "roundup()"
case also handles.
At the same time, in the case you are talking about, I really do
suspect that we have a (non-constant) power of two, and that you
should have just used "round_up()" which works fine regardless of
size, and is always efficient.
On a slight tangent.. Maybe we should have something like this:
#define size_fn(x, prefix, ...) ({ \
typeof(x) __ret; \
switch (sizeof(x)) { \
case 1: __ret = prefix##8(__VA_ARGS__); break; \
case 2: __ret = prefix##16(__VA_ARGS__); break; \
case 4: __ret = prefix##32(__VA_ARGS__); break; \
case 8: __ret = prefix##64(__VA_ARGS__); break; \
default: __ret = prefix##bad(__VA_ARGS__); \
} __ret; })
#define type_fn(x, prefix, ...) ({ \
typeof(x) __ret; \
if ((typeof(x))-1 > 1) \
__ret = size_fn(x, prefix##_u, __VA_ARGS__); \
else \
__ret = size_fn(x, prefix##_s, __VA_ARGS__); \
__ret; })
which would allow typed integer functions like this. So you could do
something like
#define round_up(x, y) size_fn(x, round_up_size, x, y)
and then you define functions for round_up_size8/16/32/64 (and you
have toi declare - but not define - round_up_sizebad()).
Of course, you probably want the usual "at least use 'int'" semantics,
in which case the "type" should be "(x)+0":
#define round_up(x, y) size_fn((x)+0, round_up_size, x, y)
and the 8-bit and 16-bit cases will never be used.
We have a lot of cases where we end up using "type overloading" by
size. The most explicit case is perhaps "get_user()" and "put_user()",
but this whole round_up thing is another example.
Maybe we never really care about "char" and "short", and always want
just the "int-vs-long-vs-longlong"? That would make the cases simpler
(32 and 64). And maybe we never care about sign. But we could try to
have some unified helper model like the above..
Linus
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Kees Cook @ 2019-05-23 16:38 UTC (permalink / raw)
To: Catalin Marinas
Cc: enh, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz, Linux ARM,
Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <20190523144449.waam2mkyzhjpqpur@mbp>
On Thu, May 23, 2019 at 03:44:49PM +0100, Catalin Marinas wrote:
> There is also the obvious requirement which I didn't mention: new user
> space continues to run on new/subsequent kernel versions. That's one of
> the points of contention for this series (ignoring MTE) with the
> maintainers having to guarantee this without much effort. IOW, do the
> 500K+ new lines in a subsequent kernel version break any user space out
> there? I'm only talking about the relaxed TBI ABI. Are the usual LTP,
> syskaller sufficient? Better static analysis would definitely help.
We can't have perfect coverage of people actively (or accidentally)
working to trick static analyzers (and the compiler) into "forgetting"
about a __user annotation. We can certainly improve analysis (I see
the other sub-thread on that), but I'd like that work not to block
this series.
What on this front would you be comfortable with? Given it's a new
feature isn't it sufficient to have a CONFIG (and/or boot option)?
> Or, if we ever want MTE to be turned on by default (i.e. tag checking),
> even if everything is tagged with 0, we have to disallow TBI for user
> and this includes hwasan. There were a small number of programs using
> the TBI (I think some JavaScript compilers tried this). But now we are
> bringing in the hwasan support and this can be a large user base. Shall
> we add an ELF note for such binaries that use TBI/hwasan?
Just to be clear, you say "disallow TBI for user" -- you mean a
particular process, yes? i.e. there is no architectural limitation that
says once we're using MTE nothing can switch to TBI. i.e. a process is
either doing MTE or TBI (or nothing, but that's the same as TBI).
> This needs solving as well. Most driver developers won't know why
> untagged_addr() is needed unless we have more rigorous types or type
> annotations and a tool to check them (we should probably revive the old
> sparse thread).
This seems like a parallel concern: we can do that separately from this
series. Without landing it, is it much harder for people to test it,
look for bugs, help with types/annotations, etc.
> > So there needs to be some way to let the kernel know which of three
> > things it should be doing:
> > 1- leaving userspace addresses as-is (present)
> > 2- wiping the top bits before using (this series)
>
> (I'd say tolerating rather than wiping since get_user still uses the tag
> in the current series)
>
> The current series does not allow any choice between 1 and 2, the
> default ABI basically becomes option 2.
What about testing tools that intentionally insert high bits for syscalls
and are _expecting_ them to fail? It seems the TBI series will break them?
In that case, do we need to opt into TBI as well?
> > 3- wiping the top bits for most things, but retaining them for MTE as
> > needed (the future)
>
> 2 and 3 are not entirely compatible as a tagged pointer may be checked
> against the memory colour by the hardware. So you can't have hwasan
> binary with MTE enabled.
Right: a process must be either MTE or TBI, not both.
> > I expect MTE to be the "default" in the future. Once a system's libc has
> > grown support for it, everything will be trying to use MTE. TBI will be
> > the special case (but TBI is effectively a prerequisite).
>
> The kernel handling of tagged pointers is indeed a prerequisite. The ABI
> distinction between the above 2 and 3 needs to be solved.
Does that need solving now or when the MTE series appears? As there is
no reason to distinguish between "normal" and "TBI", that doesn't seem
to need solving at this point?
> > AFAICT, the only difference I see between 2 and 3 will be the tag handling
> > in usercopy (all other places will continue to ignore the top bits). Is
> > that accurate?
>
> Yes, mostly (for the kernel). If MTE is enabled by default for a hwasan
> binary, it will SEGFAULT (either in user space or in kernel uaccess).
> How does the kernel choose between 2 and 3?
Right -- that was my question as well.
> > Is "1" a per-process state we want to keep? (I assume not, but rather it
> > is available via no TBI/MTE CONFIG or a boot-time option, if at all?)
>
> Possibly, though not necessarily per process. For testing or if
> something goes wrong during boot, a command line option with a static
> label would do. The AT_FLAGS bit needs to be checked by user space. My
> preference would be per-process.
I would agree.
> > To choose between "2" and "3", it seems we need a per-process flag to
> > opt into TBI (and out of MTE).
>
> Or leave option 2 the default and get it to opt in to MTE.
Given that MTE has to "start" at some point in the binary lifetime, I'm
fine with opting into MTE. I do expect, though, this will feel redundant
in a couple years as everything will immediately opt-in. But, okay, this
is therefore an issue for the MTE series.
> The current plan is that a future binary issues a prctl(), after
> checking the HWCAP_MTE bit (as I replied to Elliot, the MTE instructions
> are not in the current NOP space). I'd expect this to be done by the
> libc or dynamic loader under the assumption that the binaries it loads
> do _not_ use the top pointer byte for anything else. With hwasan
> compiled objects this gets more confusing (any ELF note to identify
> them?).
Okay, sounds fine.
> (there is also the risk of existing applications using TBI already but
> I'm not aware of any still using this feature other than hwasan)
Correct.
Alright, the tl;dr appears to be:
- you want more assurances that we can find __user stripping in the
kernel more easily. (But this seems like a parallel problem.)
- we might need to opt in to TBI with a prctl()
- all other concerns are for the future MTE series (though it sounds
like HWCAP_MTE and a prctl() solve those issues too).
Is this accurate? What do you see as the blockers for this series at
this point?
--
Kees Cook
^ permalink raw reply
* Re: [PATCH v4 0/1] Use HMM for ODP v4
From: Jason Gunthorpe @ 2019-05-23 16:34 UTC (permalink / raw)
To: Jerome Glisse
Cc: linux-kernel, linux-rdma, Leon Romanovsky, Doug Ledford,
Artemy Kovalyov, Moni Shoua, Mike Marciniszyn, Kaike Wan,
Dennis Dalessandro
In-Reply-To: <20190523155207.GC5104@redhat.com>
On Thu, May 23, 2019 at 11:52:08AM -0400, Jerome Glisse wrote:
> On Thu, May 23, 2019 at 12:41:49PM -0300, Jason Gunthorpe wrote:
> > On Thu, May 23, 2019 at 11:04:32AM -0400, Jerome Glisse wrote:
> > > On Wed, May 22, 2019 at 08:57:37PM -0300, Jason Gunthorpe wrote:
> > > > On Wed, May 22, 2019 at 01:48:52PM -0400, Jerome Glisse wrote:
> > > >
> > > > > > > So attached is a rebase on top of 5.2-rc1, i have tested with pingpong
> > > > > > > (prefetch and not and different sizes). Seems to work ok.
> > > > > >
> > > > > > Urk, it already doesn't apply to the rdma tree :(
> > > > > >
> > > > > > The conflicts are a little more extensive than I'd prefer to handle..
> > > > > > Can I ask you to rebase it on top of this branch please:
> > > > > >
> > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-for-next
> > > > > >
> > > > > > Specifically it conflicts with this patch:
> > > > > >
> > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?h=wip/jgg-for-next&id=d2183c6f1958e6b6dfdde279f4cee04280710e34
> > > >
> > > > There is at least one more serious blocker here:
> > > >
> > > > config ARCH_HAS_HMM_MIRROR
> > > > bool
> > > > default y
> > > > depends on (X86_64 || PPC64)
> > > > depends on MMU && 64BIT
> > > >
> > > > I can't loose ARM64 support for ODP by merging this, that is too
> > > > serious of a regression.
> > > >
> > > > Can you fix it?
> > >
> > > 5.2 already has patch to fix the Kconfig (ARCH_HAS_HMM_MIRROR and
> > > ARCH_HAS_HMM_DEVICE replacing ARCH_HAS_HMM) I need to update nouveau
> >
> > Newer than 5.2-rc1? Is this why ARCH_HAS_HMM_MIRROR is not used anywhere?
>
> Yes this is multi-step update, first add the new Kconfig release n,
> update driver in release n+1, update core Kconfig in release n+2
>
> So we are in release n (5.2), in 5.3 i will update nouveau and amdgpu
> so that in 5.4 in ca remove the old ARCH_HAS_HMM
Why don't you just send the patch for both parts to mm or to DRM?
This is very normal - as long as the resulting conflicts would be
small during there is no reason not to do this. Can you share the
combined patch?
> > If mm takes the fixup patches so hmm mirror is as reliable as ODP's
> > existing stuff, and patch from you to enable ARM64, then we can
> > continue to merge into 5.3
> >
> > So, let us try to get acks on those other threads..
>
> I will be merging your patchset and Ralph and repost, they are only
> minor change mostly that you can not update the driver API in just
> one release.
Of course you can, we do it all the time. It requires some
co-ordination, but as long as the merge conflicts are not big it is
fine.
Merge the driver API change and the call site updates to -mm and
refain from merging horrendously conflicting patches through DRM.
In the case of the changes in my HMM RFC it is something like 2
lines in DRM that need touching, no problem at all.
If you want help I can volunteer make a hmm PR for Linus just for this
during the merge window - but Andrew would need to agree and ack the
patches.
Jason
^ permalink raw reply
* Re: [PATCH v4 0/1] Use HMM for ODP v4
From: Jerome Glisse @ 2019-05-23 15:52 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-kernel, linux-rdma, Leon Romanovsky, Doug Ledford,
Artemy Kovalyov, Moni Shoua, Mike Marciniszyn, Kaike Wan,
Dennis Dalessandro
In-Reply-To: <20190523154149.GB12159@ziepe.ca>
On Thu, May 23, 2019 at 12:41:49PM -0300, Jason Gunthorpe wrote:
> On Thu, May 23, 2019 at 11:04:32AM -0400, Jerome Glisse wrote:
> > On Wed, May 22, 2019 at 08:57:37PM -0300, Jason Gunthorpe wrote:
> > > On Wed, May 22, 2019 at 01:48:52PM -0400, Jerome Glisse wrote:
> > >
> > > > > > So attached is a rebase on top of 5.2-rc1, i have tested with pingpong
> > > > > > (prefetch and not and different sizes). Seems to work ok.
> > > > >
> > > > > Urk, it already doesn't apply to the rdma tree :(
> > > > >
> > > > > The conflicts are a little more extensive than I'd prefer to handle..
> > > > > Can I ask you to rebase it on top of this branch please:
> > > > >
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-for-next
> > > > >
> > > > > Specifically it conflicts with this patch:
> > > > >
> > > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?h=wip/jgg-for-next&id=d2183c6f1958e6b6dfdde279f4cee04280710e34
> > >
> > > There is at least one more serious blocker here:
> > >
> > > config ARCH_HAS_HMM_MIRROR
> > > bool
> > > default y
> > > depends on (X86_64 || PPC64)
> > > depends on MMU && 64BIT
> > >
> > > I can't loose ARM64 support for ODP by merging this, that is too
> > > serious of a regression.
> > >
> > > Can you fix it?
> >
> > 5.2 already has patch to fix the Kconfig (ARCH_HAS_HMM_MIRROR and
> > ARCH_HAS_HMM_DEVICE replacing ARCH_HAS_HMM) I need to update nouveau
>
> Newer than 5.2-rc1? Is this why ARCH_HAS_HMM_MIRROR is not used anywhere?
Yes this is multi-step update, first add the new Kconfig release n,
update driver in release n+1, update core Kconfig in release n+2
So we are in release n (5.2), in 5.3 i will update nouveau and amdgpu
so that in 5.4 in ca remove the old ARCH_HAS_HMM
> > in 5.3 so that i can drop the old ARCH_HAS_HMM and then convert
> > core mm in 5.4 to use ARCH_HAS_HMM_MIRROR and ARCH_HAS_HMM_DEVICE
> > instead of ARCH_HAS_HMM
>
> My problem is that ODP needs HMM_MIRROR which needs HMM & ARCH_HAS_HMM
> - and then even if fixed we still have the ARCH_HAS_HMM_MIRROR
> restricted to ARM64..
>
> Can we broaden HMM_MIRROR to all arches? I would very much prefer
> that.
Ignore ARCH_HAS_HMM it will be remove in 5.4, all that will matter
for ODP is ARCH_HAS_HMM_MIRROR which should be enabled for ARM64 as
ARM64 has everything needed for that. I just did not add ARM64 to
ARCH_HAS_HMM_MIRROR because i did not had hardware to test it on.
So in 5.3 i will update nouveau and amdgpu to use ARCH_HAS_HMM_DEVICE
and ARCH_HAS_HMM_MIRROR. In 5.4 i will update mm/Kconig to remove
ARCH_HAS_HMM
>
> > So it seems it will have to wait 5.4 for ODP. I will re-spin the
> > patch for ODP once i am done reviewing Ralph changes and yours
> > for 5.3.
>
> I think we are still OK for 5.3.
I can not update mm/Kconfig in 5.3 so any Kconfig update will be
5.4
>
> If mm takes the fixup patches so hmm mirror is as reliable as ODP's
> existing stuff, and patch from you to enable ARM64, then we can
> continue to merge into 5.3
>
> So, let us try to get acks on those other threads..
I will be merging your patchset and Ralph and repost, they are only
minor change mostly that you can not update the driver API in just
one release. First add the new API in release n, then replace old
API usage in release n+1, then remove old API in n+2.
Cheers,
Jérôme
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: enh @ 2019-05-23 15:44 UTC (permalink / raw)
To: Catalin Marinas
Cc: Kees Cook, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz,
Linux ARM, Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <20190523144449.waam2mkyzhjpqpur@mbp>
On Thu, May 23, 2019 at 7:45 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
>
> On Wed, May 22, 2019 at 01:47:36PM -0700, Kees Cook wrote:
> > On Wed, May 22, 2019 at 05:35:27PM +0100, Catalin Marinas wrote:
> > > The two hard requirements I have for supporting any new hardware feature
> > > in Linux are (1) a single kernel image binary continues to run on old
> > > hardware while making use of the new feature if available and (2) old
> > > user space continues to run on new hardware while new user space can
> > > take advantage of the new feature.
> >
> > Agreed! And I think the series meets these requirements, yes?
>
> Yes. I mentioned this just to make sure people don't expect different
> kernel builds for different hardware features.
>
> There is also the obvious requirement which I didn't mention: new user
> space continues to run on new/subsequent kernel versions. That's one of
> the points of contention for this series (ignoring MTE) with the
> maintainers having to guarantee this without much effort. IOW, do the
> 500K+ new lines in a subsequent kernel version break any user space out
> there? I'm only talking about the relaxed TBI ABI. Are the usual LTP,
> syskaller sufficient? Better static analysis would definitely help.
>
> > > For MTE, we just can't enable it by default since there are applications
> > > who use the top byte of a pointer and expect it to be ignored rather
> > > than failing with a mismatched tag. Just think of a hwasan compiled
> > > binary where TBI is expected to work and you try to run it with MTE
> > > turned on.
> >
> > Ah! Okay, here's the use-case I wasn't thinking of: the concern is TBI
> > conflicting with MTE. And anything that starts using TBI suddenly can't
> > run in the future because it's being interpreted as MTE bits? (Is that
> > the ABI concern?
>
> That's another aspect to figure out when we add the MTE support. I don't
> think we'd be able to do this without an explicit opt-in by the user.
>
> Or, if we ever want MTE to be turned on by default (i.e. tag checking),
> even if everything is tagged with 0, we have to disallow TBI for user
> and this includes hwasan. There were a small number of programs using
> the TBI (I think some JavaScript compilers tried this). But now we are
> bringing in the hwasan support and this can be a large user base. Shall
> we add an ELF note for such binaries that use TBI/hwasan?
>
> This series is still required for MTE but we may decide not to relax the
> ABI blindly, therefore the opt-in (prctl) or personality idea.
>
> > I feel like we got into the weeds about ioctl()s and one-off bugs...)
>
> This needs solving as well. Most driver developers won't know why
> untagged_addr() is needed unless we have more rigorous types or type
> annotations and a tool to check them (we should probably revive the old
> sparse thread).
>
> > So there needs to be some way to let the kernel know which of three
> > things it should be doing:
> > 1- leaving userspace addresses as-is (present)
> > 2- wiping the top bits before using (this series)
>
> (I'd say tolerating rather than wiping since get_user still uses the tag
> in the current series)
>
> The current series does not allow any choice between 1 and 2, the
> default ABI basically becomes option 2.
>
> > 3- wiping the top bits for most things, but retaining them for MTE as
> > needed (the future)
>
> 2 and 3 are not entirely compatible as a tagged pointer may be checked
> against the memory colour by the hardware. So you can't have hwasan
> binary with MTE enabled.
>
> > I expect MTE to be the "default" in the future. Once a system's libc has
> > grown support for it, everything will be trying to use MTE. TBI will be
> > the special case (but TBI is effectively a prerequisite).
>
> The kernel handling of tagged pointers is indeed a prerequisite. The ABI
> distinction between the above 2 and 3 needs to be solved.
>
> > AFAICT, the only difference I see between 2 and 3 will be the tag handling
> > in usercopy (all other places will continue to ignore the top bits). Is
> > that accurate?
>
> Yes, mostly (for the kernel). If MTE is enabled by default for a hwasan
> binary, it will SEGFAULT (either in user space or in kernel uaccess).
> How does the kernel choose between 2 and 3?
>
> > Is "1" a per-process state we want to keep? (I assume not, but rather it
> > is available via no TBI/MTE CONFIG or a boot-time option, if at all?)
>
> Possibly, though not necessarily per process. For testing or if
> something goes wrong during boot, a command line option with a static
> label would do. The AT_FLAGS bit needs to be checked by user space. My
> preference would be per-process.
>
> > To choose between "2" and "3", it seems we need a per-process flag to
> > opt into TBI (and out of MTE).
>
> Or leave option 2 the default and get it to opt in to MTE.
>
> > For userspace, how would a future binary choose TBI over MTE? If it's
> > a library issue, we can't use an ELF bit, since the choice may be
> > "late" after ELF load (this implies the need for a prctl().) If it's
> > binary-only ("built with HWKASan") then an ELF bit seems sufficient.
> > And without the marking, I'd expect the kernel to enforce MTE when
> > there are high bits.
>
> The current plan is that a future binary issues a prctl(), after
> checking the HWCAP_MTE bit (as I replied to Elliot, the MTE instructions
> are not in the current NOP space). I'd expect this to be done by the
> libc or dynamic loader under the assumption that the binaries it loads
> do _not_ use the top pointer byte for anything else.
yeah, it sounds like to support hwasan and MTE, the dynamic linker
will need to not use either itself.
> With hwasan
> compiled objects this gets more confusing (any ELF note to identify
> them?).
no, at the moment code that wants to know checks for the presence of
__hwasan_init. (and bionic doesn't actually look at any ELF notes
right now.) but we can always add something if we need to.
> (there is also the risk of existing applications using TBI already but
> I'm not aware of any still using this feature other than hwasan)
>
> --
> Catalin
^ permalink raw reply
* Re: [PATCH v4 0/1] Use HMM for ODP v4
From: Jason Gunthorpe @ 2019-05-23 15:41 UTC (permalink / raw)
To: Jerome Glisse
Cc: linux-kernel, linux-rdma, Leon Romanovsky, Doug Ledford,
Artemy Kovalyov, Moni Shoua, Mike Marciniszyn, Kaike Wan,
Dennis Dalessandro
In-Reply-To: <20190523150432.GA5104@redhat.com>
On Thu, May 23, 2019 at 11:04:32AM -0400, Jerome Glisse wrote:
> On Wed, May 22, 2019 at 08:57:37PM -0300, Jason Gunthorpe wrote:
> > On Wed, May 22, 2019 at 01:48:52PM -0400, Jerome Glisse wrote:
> >
> > > > > So attached is a rebase on top of 5.2-rc1, i have tested with pingpong
> > > > > (prefetch and not and different sizes). Seems to work ok.
> > > >
> > > > Urk, it already doesn't apply to the rdma tree :(
> > > >
> > > > The conflicts are a little more extensive than I'd prefer to handle..
> > > > Can I ask you to rebase it on top of this branch please:
> > > >
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-for-next
> > > >
> > > > Specifically it conflicts with this patch:
> > > >
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?h=wip/jgg-for-next&id=d2183c6f1958e6b6dfdde279f4cee04280710e34
> >
> > There is at least one more serious blocker here:
> >
> > config ARCH_HAS_HMM_MIRROR
> > bool
> > default y
> > depends on (X86_64 || PPC64)
> > depends on MMU && 64BIT
> >
> > I can't loose ARM64 support for ODP by merging this, that is too
> > serious of a regression.
> >
> > Can you fix it?
>
> 5.2 already has patch to fix the Kconfig (ARCH_HAS_HMM_MIRROR and
> ARCH_HAS_HMM_DEVICE replacing ARCH_HAS_HMM) I need to update nouveau
Newer than 5.2-rc1? Is this why ARCH_HAS_HMM_MIRROR is not used anywhere?
> in 5.3 so that i can drop the old ARCH_HAS_HMM and then convert
> core mm in 5.4 to use ARCH_HAS_HMM_MIRROR and ARCH_HAS_HMM_DEVICE
> instead of ARCH_HAS_HMM
My problem is that ODP needs HMM_MIRROR which needs HMM & ARCH_HAS_HMM
- and then even if fixed we still have the ARCH_HAS_HMM_MIRROR
restricted to ARM64..
Can we broaden HMM_MIRROR to all arches? I would very much prefer
that.
> So it seems it will have to wait 5.4 for ODP. I will re-spin the
> patch for ODP once i am done reviewing Ralph changes and yours
> for 5.3.
I think we are still OK for 5.3.
If mm takes the fixup patches so hmm mirror is as reliable as ODP's
existing stuff, and patch from you to enable ARM64, then we can
continue to merge into 5.3
So, let us try to get acks on those other threads..
Jason
^ permalink raw reply
* Re: [PATCH 1/1] infiniband/mm: convert put_page() to put_user_page*()
From: Jerome Glisse @ 2019-05-23 15:31 UTC (permalink / raw)
To: john.hubbard
Cc: Andrew Morton, linux-mm, Jason Gunthorpe, LKML, linux-rdma,
linux-fsdevel, John Hubbard, Doug Ledford, Mike Marciniszyn,
Dennis Dalessandro, Christian Benvenuti, Jan Kara,
Jason Gunthorpe, Ira Weiny
In-Reply-To: <20190523072537.31940-2-jhubbard@nvidia.com>
On Thu, May 23, 2019 at 12:25:37AM -0700, john.hubbard@gmail.com wrote:
> From: John Hubbard <jhubbard@nvidia.com>
>
> For infiniband code that retains pages via get_user_pages*(),
> release those pages via the new put_user_page(), or
> put_user_pages*(), instead of put_page()
>
> This is a tiny part of the second step of fixing the problem described
> in [1]. The steps are:
>
> 1) Provide put_user_page*() routines, intended to be used
> for releasing pages that were pinned via get_user_pages*().
>
> 2) Convert all of the call sites for get_user_pages*(), to
> invoke put_user_page*(), instead of put_page(). This involves dozens of
> call sites, and will take some time.
>
> 3) After (2) is complete, use get_user_pages*() and put_user_page*() to
> implement tracking of these pages. This tracking will be separate from
> the existing struct page refcounting.
>
> 4) Use the tracking and identification of these pages, to implement
> special handling (especially in writeback paths) when the pages are
> backed by a filesystem. Again, [1] provides details as to why that is
> desirable.
>
> [1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()"
>
> Cc: Doug Ledford <dledford@redhat.com>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
> Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
> Cc: Christian Benvenuti <benve@cisco.com>
>
> Reviewed-by: Jan Kara <jack@suse.cz>
> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
> Acked-by: Jason Gunthorpe <jgg@mellanox.com>
> Tested-by: Ira Weiny <ira.weiny@intel.com>
> Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Reviewed-by: Jérôme Glisse <jglisse@redhat.com>
Between i have a wishlist see below
> ---
> drivers/infiniband/core/umem.c | 7 ++++---
> drivers/infiniband/core/umem_odp.c | 10 +++++-----
> drivers/infiniband/hw/hfi1/user_pages.c | 11 ++++-------
> drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++---
> drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++++-------
> drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +++---
> drivers/infiniband/hw/usnic/usnic_uiom.c | 7 ++++---
> 7 files changed, 27 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> index e7ea819fcb11..673f0d240b3e 100644
> --- a/drivers/infiniband/core/umem.c
> +++ b/drivers/infiniband/core/umem.c
> @@ -54,9 +54,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
>
> for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->sg_nents, 0) {
> page = sg_page_iter_page(&sg_iter);
> - if (!PageDirty(page) && umem->writable && dirty)
> - set_page_dirty_lock(page);
> - put_page(page);
> + if (umem->writable && dirty)
> + put_user_pages_dirty_lock(&page, 1);
> + else
> + put_user_page(page);
Can we get a put_user_page_dirty(struct page 8*pages, bool dirty, npages) ?
It is a common pattern that we might have to conditionaly dirty the pages
and i feel it would look cleaner if we could move the branch within the
put_user_page*() function.
Cheers,
Jérôme
^ permalink raw reply
* Re: [RFC][PATCH] kernel.h: Add generic roundup_64() macro
From: Steven Rostedt @ 2019-05-23 15:27 UTC (permalink / raw)
To: Linus Torvalds
Cc: LKML, Ben Skeggs, David Airlie, Daniel Vetter, Leon Romanovsky,
Doug Ledford, Jason Gunthorpe, Darrick J. Wong, linux-xfs,
dri-devel, nouveau, linux-rdma, Andrew Morton
In-Reply-To: <CAHk-=wg5HqJ2Kfgpub+tCWQ2_FiFwEW9H1Rm+an-BLGaGvDDXw@mail.gmail.com>
On Thu, 23 May 2019 08:10:44 -0700
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Thu, May 23, 2019 at 7:00 AM Steven Rostedt <rostedt@goodmis.org> wrote:
> >
> > +# define roundup_64(x, y) ( \
> > +{ \
> > + typeof(y) __y = y; \
> > + typeof(x) __x = (x) + (__y - 1); \
> > + do_div(__x, __y); \
> > + __x * __y; \
> > +} \
>
> The thing about this is that it absolutely sucks for power-of-two arguments.
>
> The regular roundup() that uses division has the compiler at least
> optimize them to shifts - at least for constant cases. But do_div() is
> meant for "we already know it's not a power of two", and the compiler
> doesn't have any understanding of the internals.
>
> And it looks to me like the use case you want this for is very much
> probably a power of two. In which case division is all kinds of just
> stupid.
>
> And we already have a power-of-two round up function that works on
> u64. It's called "round_up()".
>
> I wish we had a better visual warning about the differences between
> "round_up()" (limited to powers-of-two, but efficient, and works with
> any size) and "roundup()" (generic, potentially horribly slow, and
> doesn't work for 64-bit on 32-bit).
>
> Side note: "round_up()" has the problem that it uses "x" twice.
>
> End result: somebody should look at this, but I really don't like the
> "force division" case that is likely horribly slow and nasty.
I haven't yet tested this, but what about something like the following:
# define roundup_64(x, y) ( \
{ \
typeof(y) __y; \
typeof(x) __x; \
\
if (__builtin_constant_p(y) && \
!(y & (y >> 1))) { \
__x = round_up(x, y); \
} else { \
__y = y; \
__x = (x) + (__y - 1); \
do_div(__x, __y); \
__x = __x * __y; \
} \
__x; \
} \
)
If the compiler knows enough that y is a power of two, it will use the
shift version. Otherwise, it doesn't know enough and would divide
regardless. Or perhaps forget about the constant check, and just force
the power of two check:
# define roundup_64(x, y) ( \
{ \
typeof(y) __y = y; \
typeof(x) __x; \
\
if (!(__y & (__y >> 1))) { \
__x = round_up(x, y); \
} else { \
__x = (x) + (__y - 1); \
do_div(__x, __y); \
__x = __x * __y; \
} \
__x; \
} \
)
This way even if the compiler doesn't know that this is a power of two,
it will still do the shift if y ends up being one.
-- Steve
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 15:21 UTC (permalink / raw)
To: enh
Cc: Kees Cook, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz,
Linux ARM, Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <CAJgzZooc+wXBBXenm62n2zR8TVrv-y1pXMmHSdxeaNYhFLSzBA@mail.gmail.com>
On Wed, May 22, 2019 at 09:58:22AM -0700, enh wrote:
> i was questioning the argument about the ioctl issues, and saying that
> from my perspective, untagging bugs are not really any different than
> any other kind of kernel bug.
Once this series gets in, they are indeed just kernel bugs. What I want
is an easier way to identify them, ideally before they trigger in the
field.
> i still don't see how this isn't just a regular testing/CI issue, the
> same as any other kind of kernel bug. it's already the case that i can
> get a bad kernel...
The testing would have a smaller code coverage in terms of drivers,
filesystems than something like a static checker (though one does not
exclude the other).
--
Catalin
^ permalink raw reply
* Re: [RFC][PATCH] kernel.h: Add generic roundup_64() macro
From: Linus Torvalds @ 2019-05-23 15:10 UTC (permalink / raw)
To: Steven Rostedt
Cc: LKML, Ben Skeggs, David Airlie, Daniel Vetter, Leon Romanovsky,
Doug Ledford, Jason Gunthorpe, Darrick J. Wong, linux-xfs,
dri-devel, nouveau, linux-rdma, Andrew Morton
In-Reply-To: <20190523100013.52a8d2a6@gandalf.local.home>
On Thu, May 23, 2019 at 7:00 AM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> +# define roundup_64(x, y) ( \
> +{ \
> + typeof(y) __y = y; \
> + typeof(x) __x = (x) + (__y - 1); \
> + do_div(__x, __y); \
> + __x * __y; \
> +} \
The thing about this is that it absolutely sucks for power-of-two arguments.
The regular roundup() that uses division has the compiler at least
optimize them to shifts - at least for constant cases. But do_div() is
meant for "we already know it's not a power of two", and the compiler
doesn't have any understanding of the internals.
And it looks to me like the use case you want this for is very much
probably a power of two. In which case division is all kinds of just
stupid.
And we already have a power-of-two round up function that works on
u64. It's called "round_up()".
I wish we had a better visual warning about the differences between
"round_up()" (limited to powers-of-two, but efficient, and works with
any size) and "roundup()" (generic, potentially horribly slow, and
doesn't work for 64-bit on 32-bit).
Side note: "round_up()" has the problem that it uses "x" twice.
End result: somebody should look at this, but I really don't like the
"force division" case that is likely horribly slow and nasty.
Linus
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 15:08 UTC (permalink / raw)
To: Kees Cook
Cc: enh, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz, Linux ARM,
Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <201905221157.A9BAB1F296@keescook>
On Wed, May 22, 2019 at 12:21:27PM -0700, Kees Cook wrote:
> If a process wants to not tag, that's also up to the allocator where
> it can decide not to ask the kernel, and just not tag. Nothing breaks in
> userspace if a process is NOT tagging and untagged_addr() exists or is
> missing. This, I think, is the core way this doesn't trip over the
> golden rule: an old system image will run fine (because it's not
> tagging). A *new* system may encounter bugs with tagging because it's a
> new feature: this is The Way Of Things. But we don't break old userspace
> because old userspace isn't using tags.
With this series and hwasan binaries, at some point in the future they
will be considered "old userspace" and they do use pointer tags which
expect to be ignored by both the hardware and the kernel. MTE breaks
this assumption.
--
Catalin
^ permalink raw reply
* Re: [PATCH v4 0/1] Use HMM for ODP v4
From: Jerome Glisse @ 2019-05-23 15:04 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-kernel, linux-rdma, Leon Romanovsky, Doug Ledford,
Artemy Kovalyov, Moni Shoua, Mike Marciniszyn, Kaike Wan,
Dennis Dalessandro
In-Reply-To: <20190522235737.GD15389@ziepe.ca>
On Wed, May 22, 2019 at 08:57:37PM -0300, Jason Gunthorpe wrote:
> On Wed, May 22, 2019 at 01:48:52PM -0400, Jerome Glisse wrote:
>
> > > > So attached is a rebase on top of 5.2-rc1, i have tested with pingpong
> > > > (prefetch and not and different sizes). Seems to work ok.
> > >
> > > Urk, it already doesn't apply to the rdma tree :(
> > >
> > > The conflicts are a little more extensive than I'd prefer to handle..
> > > Can I ask you to rebase it on top of this branch please:
> > >
> > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/log/?h=wip/jgg-for-next
> > >
> > > Specifically it conflicts with this patch:
> > >
> > > https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git/commit/?h=wip/jgg-for-next&id=d2183c6f1958e6b6dfdde279f4cee04280710e34
>
> There is at least one more serious blocker here:
>
> config ARCH_HAS_HMM_MIRROR
> bool
> default y
> depends on (X86_64 || PPC64)
> depends on MMU && 64BIT
>
> I can't loose ARM64 support for ODP by merging this, that is too
> serious of a regression.
>
> Can you fix it?
5.2 already has patch to fix the Kconfig (ARCH_HAS_HMM_MIRROR and
ARCH_HAS_HMM_DEVICE replacing ARCH_HAS_HMM) I need to update nouveau
in 5.3 so that i can drop the old ARCH_HAS_HMM and then convert
core mm in 5.4 to use ARCH_HAS_HMM_MIRROR and ARCH_HAS_HMM_DEVICE
instead of ARCH_HAS_HMM
Adding ARM64 to ARCH_HAS_HMM_MIRROR should not be an issue i would
need access to an ARM64 to test as i did not wanted to enable it
without testing.
So it seems it will have to wait 5.4 for ODP. I will re-spin the
patch for ODP once i am done reviewing Ralph changes and yours
for 5.3.
Cheers,
Jérôme
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 14:44 UTC (permalink / raw)
To: Kees Cook
Cc: enh, Evgenii Stepanov, Andrey Konovalov, Khalid Aziz, Linux ARM,
Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <201905221316.865581CF@keescook>
On Wed, May 22, 2019 at 01:47:36PM -0700, Kees Cook wrote:
> On Wed, May 22, 2019 at 05:35:27PM +0100, Catalin Marinas wrote:
> > The two hard requirements I have for supporting any new hardware feature
> > in Linux are (1) a single kernel image binary continues to run on old
> > hardware while making use of the new feature if available and (2) old
> > user space continues to run on new hardware while new user space can
> > take advantage of the new feature.
>
> Agreed! And I think the series meets these requirements, yes?
Yes. I mentioned this just to make sure people don't expect different
kernel builds for different hardware features.
There is also the obvious requirement which I didn't mention: new user
space continues to run on new/subsequent kernel versions. That's one of
the points of contention for this series (ignoring MTE) with the
maintainers having to guarantee this without much effort. IOW, do the
500K+ new lines in a subsequent kernel version break any user space out
there? I'm only talking about the relaxed TBI ABI. Are the usual LTP,
syskaller sufficient? Better static analysis would definitely help.
> > For MTE, we just can't enable it by default since there are applications
> > who use the top byte of a pointer and expect it to be ignored rather
> > than failing with a mismatched tag. Just think of a hwasan compiled
> > binary where TBI is expected to work and you try to run it with MTE
> > turned on.
>
> Ah! Okay, here's the use-case I wasn't thinking of: the concern is TBI
> conflicting with MTE. And anything that starts using TBI suddenly can't
> run in the future because it's being interpreted as MTE bits? (Is that
> the ABI concern?
That's another aspect to figure out when we add the MTE support. I don't
think we'd be able to do this without an explicit opt-in by the user.
Or, if we ever want MTE to be turned on by default (i.e. tag checking),
even if everything is tagged with 0, we have to disallow TBI for user
and this includes hwasan. There were a small number of programs using
the TBI (I think some JavaScript compilers tried this). But now we are
bringing in the hwasan support and this can be a large user base. Shall
we add an ELF note for such binaries that use TBI/hwasan?
This series is still required for MTE but we may decide not to relax the
ABI blindly, therefore the opt-in (prctl) or personality idea.
> I feel like we got into the weeds about ioctl()s and one-off bugs...)
This needs solving as well. Most driver developers won't know why
untagged_addr() is needed unless we have more rigorous types or type
annotations and a tool to check them (we should probably revive the old
sparse thread).
> So there needs to be some way to let the kernel know which of three
> things it should be doing:
> 1- leaving userspace addresses as-is (present)
> 2- wiping the top bits before using (this series)
(I'd say tolerating rather than wiping since get_user still uses the tag
in the current series)
The current series does not allow any choice between 1 and 2, the
default ABI basically becomes option 2.
> 3- wiping the top bits for most things, but retaining them for MTE as
> needed (the future)
2 and 3 are not entirely compatible as a tagged pointer may be checked
against the memory colour by the hardware. So you can't have hwasan
binary with MTE enabled.
> I expect MTE to be the "default" in the future. Once a system's libc has
> grown support for it, everything will be trying to use MTE. TBI will be
> the special case (but TBI is effectively a prerequisite).
The kernel handling of tagged pointers is indeed a prerequisite. The ABI
distinction between the above 2 and 3 needs to be solved.
> AFAICT, the only difference I see between 2 and 3 will be the tag handling
> in usercopy (all other places will continue to ignore the top bits). Is
> that accurate?
Yes, mostly (for the kernel). If MTE is enabled by default for a hwasan
binary, it will SEGFAULT (either in user space or in kernel uaccess).
How does the kernel choose between 2 and 3?
> Is "1" a per-process state we want to keep? (I assume not, but rather it
> is available via no TBI/MTE CONFIG or a boot-time option, if at all?)
Possibly, though not necessarily per process. For testing or if
something goes wrong during boot, a command line option with a static
label would do. The AT_FLAGS bit needs to be checked by user space. My
preference would be per-process.
> To choose between "2" and "3", it seems we need a per-process flag to
> opt into TBI (and out of MTE).
Or leave option 2 the default and get it to opt in to MTE.
> For userspace, how would a future binary choose TBI over MTE? If it's
> a library issue, we can't use an ELF bit, since the choice may be
> "late" after ELF load (this implies the need for a prctl().) If it's
> binary-only ("built with HWKASan") then an ELF bit seems sufficient.
> And without the marking, I'd expect the kernel to enforce MTE when
> there are high bits.
The current plan is that a future binary issues a prctl(), after
checking the HWCAP_MTE bit (as I replied to Elliot, the MTE instructions
are not in the current NOP space). I'd expect this to be done by the
libc or dynamic loader under the assumption that the binaries it loads
do _not_ use the top pointer byte for anything else. With hwasan
compiled objects this gets more confusing (any ELF note to identify
them?).
(there is also the risk of existing applications using TBI already but
I'm not aware of any still using this feature other than hwasan)
--
Catalin
^ permalink raw reply
* [RFC][PATCH] kernel.h: Add generic roundup_64() macro
From: Steven Rostedt @ 2019-05-23 14:00 UTC (permalink / raw)
To: LKML
Cc: Leon Romanovsky, Darrick J. Wong, David Airlie,
nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
linux-xfs-u79uwXL29TY76Z2rM5mHXA, Jason Gunthorpe, Doug Ledford,
Ben Skeggs, Daniel Vetter, Andrew Morton, Linus Torvalds,
linux-rdma-u79uwXL29TY76Z2rM5mHXA
From: Steven Rostedt (VMware) <rostedt@goodmis.org>
In discussing a build failure on x86_32 due to the use of roundup() on
a 64 bit number, I realized that there's no generic equivalent
roundup_64(). It is implemented in two separate places in the kernel,
but there really should be just one that all can use.
Although the other implementations are a static inline function, this
implementation is a macro to allow the use of typeof(x) to denote the
type that is being used. If the build is on a 64 bit machine, then the
roundup_64() macro will just default back to roundup(). But for 32 bit
machines, it will use the version that is will not cause issues with
dividing a 64 bit number on a 32 bit machine.
Link: http://lkml.kernel.org/r/20190522145450.25ff483d@gandalf.local.home
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 34a998012bf6..cdacfe1f732c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -143,14 +143,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
kfree(nvbo);
}
-static inline u64
-roundup_64(u64 x, u32 y)
-{
- x += y - 1;
- do_div(x, y);
- return x * y;
-}
-
static void
nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
int *align, u64 *size)
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index edbd5a210df2..13de9d49bd52 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -207,13 +207,6 @@ static inline xfs_dev_t linux_to_xfs_dev_t(dev_t dev)
#define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
#define xfs_stack_trace() dump_stack()
-static inline uint64_t roundup_64(uint64_t x, uint32_t y)
-{
- x += y - 1;
- do_div(x, y);
- return x * y;
-}
-
static inline uint64_t howmany_64(uint64_t x, uint32_t y)
{
x += y - 1;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 74b1ee9027f5..cd0063629357 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -115,6 +115,20 @@
(((x) + (__y - 1)) / __y) * __y; \
} \
)
+
+#if BITS_PER_LONG == 32
+# define roundup_64(x, y) ( \
+{ \
+ typeof(y) __y = y; \
+ typeof(x) __x = (x) + (__y - 1); \
+ do_div(__x, __y); \
+ __x * __y; \
+} \
+)
+#else
+# define roundup_64(x, y) roundup(x, y)
+#endif
+
/**
* rounddown - round down to next specified multiple
* @x: the value to round
_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau
^ permalink raw reply related
* Re: [PATCH] RDMA/mlx5: Use DIV_ROUND_UP_ULL macro to allow 32 bit to build
From: Steven Rostedt @ 2019-05-23 13:36 UTC (permalink / raw)
To: Michal Kubecek
Cc: LKML, Leon Romanovsky, Doug Ledford, Jason Gunthorpe, linux-rdma,
Linus Torvalds
In-Reply-To: <20190523084812.325454f6@gandalf.local.home>
On Thu, 23 May 2019 08:48:12 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> I think I'll go and just add a roundup_64()!
Perhaps something like this?
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 34a998012bf6..cdacfe1f732c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -143,14 +143,6 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
kfree(nvbo);
}
-static inline u64
-roundup_64(u64 x, u32 y)
-{
- x += y - 1;
- do_div(x, y);
- return x * y;
-}
-
static void
nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
int *align, u64 *size)
diff --git a/drivers/infiniband/hw/mlx5/cmd.c b/drivers/infiniband/hw/mlx5/cmd.c
index e3ec79b8f7f5..f080df9934e8 100644
--- a/drivers/infiniband/hw/mlx5/cmd.c
+++ b/drivers/infiniband/hw/mlx5/cmd.c
@@ -190,7 +190,7 @@ int mlx5_cmd_alloc_sw_icm(struct mlx5_dm *dm, int type, u64 length,
u16 uid, phys_addr_t *addr, u32 *obj_id)
{
struct mlx5_core_dev *dev = dm->dev;
- u32 num_blocks = DIV_ROUND_UP(length, MLX5_SW_ICM_BLOCK_SIZE(dev));
+ u32 num_blocks = DIV_ROUND_UP_ULL(length, MLX5_SW_ICM_BLOCK_SIZE(dev));
u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
u32 in[MLX5_ST_SZ_DW(create_sw_icm_in)] = {};
unsigned long *block_map;
@@ -266,7 +266,7 @@ int mlx5_cmd_dealloc_sw_icm(struct mlx5_dm *dm, int type, u64 length,
u16 uid, phys_addr_t addr, u32 obj_id)
{
struct mlx5_core_dev *dev = dm->dev;
- u32 num_blocks = DIV_ROUND_UP(length, MLX5_SW_ICM_BLOCK_SIZE(dev));
+ u32 num_blocks = DIV_ROUND_UP_ULL(length, MLX5_SW_ICM_BLOCK_SIZE(dev));
u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};
unsigned long *block_map;
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index abac70ad5c7c..2d48c0e55ed2 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -2344,7 +2344,7 @@ static int handle_alloc_dm_sw_icm(struct ib_ucontext *ctx,
/* Allocation size must a multiple of the basic block size
* and a power of 2.
*/
- act_size = roundup(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
+ act_size = roundup_64(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
act_size = roundup_pow_of_two(act_size);
dm->size = act_size;
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index edbd5a210df2..13de9d49bd52 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -207,13 +207,6 @@ static inline xfs_dev_t linux_to_xfs_dev_t(dev_t dev)
#define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
#define xfs_stack_trace() dump_stack()
-static inline uint64_t roundup_64(uint64_t x, uint32_t y)
-{
- x += y - 1;
- do_div(x, y);
- return x * y;
-}
-
static inline uint64_t howmany_64(uint64_t x, uint32_t y)
{
x += y - 1;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 74b1ee9027f5..cd0063629357 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -115,6 +115,20 @@
(((x) + (__y - 1)) / __y) * __y; \
} \
)
+
+#if BITS_PER_LONG == 32
+# define roundup_64(x, y) ( \
+{ \
+ typeof(y) __y = y; \
+ typeof(x) __x = (x) + (__y - 1); \
+ do_div(__x, __y); \
+ __x * __y; \
+} \
+)
+#else
+# define roundup_64(x, y) roundup(x, y)
+#endif
+
/**
* rounddown - round down to next specified multiple
* @x: the value to round
-- Steve
^ permalink raw reply related
* Re: [PATCH] RDMA/mlx5: Use DIV_ROUND_UP_ULL macro to allow 32 bit to build
From: Steven Rostedt @ 2019-05-23 12:48 UTC (permalink / raw)
To: Michal Kubecek
Cc: LKML, Leon Romanovsky, Doug Ledford, Jason Gunthorpe, linux-rdma,
Linus Torvalds
In-Reply-To: <20190523065803.GB30439@unicorn.suse.cz>
On Thu, 23 May 2019 08:58:03 +0200
Michal Kubecek <mkubecek@suse.cz> wrote:
> > diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
> > index abac70ad5c7c..40d4c5f7ea43 100644
> > --- a/drivers/infiniband/hw/mlx5/main.c
> > +++ b/drivers/infiniband/hw/mlx5/main.c
> > @@ -2344,7 +2344,7 @@ static int handle_alloc_dm_sw_icm(struct ib_ucontext *ctx,
> > /* Allocation size must a multiple of the basic block size
> > * and a power of 2.
> > */
> > - act_size = roundup(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
> > + act_size = DIV_ROUND_UP_ULL(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
> > act_size = roundup_pow_of_two(act_size);
> >
> > dm->size = act_size;
>
> This seems wrong: roundup() rounds up to a multiple of second argument
> but DIV_ROUND_UP_ULL() would divide with rounding up.
Yeah, the macros are a bit confusing. There's unfortunately no
roundup_64() (perhaps we should make one?)
#define roundup(x, y) ( \
{ \
typeof(y) __y = y; \
(((x) + (__y - 1)) / __y) * __y; \
} \
)
#define DIV_ROUND_DOWN_ULL(ll, d) \
({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; })
#define DIV_ROUND_UP_ULL(ll, d) DIV_ROUND_DOWN_ULL((ll) + (d) - 1, (d))
roundup(a, b) == ((a + b - 1) / b) * b
DIV_ROUND_UP_ULL(a, b) DIV_ROUND_DOWN_ULL(a + b - 1, b)
= (a + b - 1) / b
Hmm, looks like you are right (damn, I thought I did this before
posting the patch, but I must have miscalculated something). It does
look like we are missing a "* b" in there.
I think I'll go and just add a roundup_64()!
Thanks for pointing this out.
-- Steve
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Dave Martin @ 2019-05-23 10:42 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Mark Rutland, kvm, Christian Koenig, Szabolcs Nagy,
Catalin Marinas, Will Deacon, dri-devel, linux-mm, Lee Smith,
linux-kselftest, Vincenzo Frascino, Jacob Bramley,
Leon Romanovsky, linux-rdma, amd-gfx, linux-arm-kernel,
Evgeniy Stepanov, linux-media, Kees Cook, Ruben Ayrapetyan,
Andrey Konovalov, Kevin Brodsky <kevin.br>
In-Reply-To: <20190523002052.GF15389@ziepe.ca>
On Wed, May 22, 2019 at 09:20:52PM -0300, Jason Gunthorpe wrote:
> On Wed, May 22, 2019 at 02:49:28PM +0100, Dave Martin wrote:
> > On Tue, May 21, 2019 at 03:48:56PM -0300, Jason Gunthorpe wrote:
> > > On Fri, May 17, 2019 at 03:49:31PM +0100, Catalin Marinas wrote:
> > >
> > > > The tagged pointers (whether hwasan or MTE) should ideally be a
> > > > transparent feature for the application writer but I don't think we can
> > > > solve it entirely and make it seamless for the multitude of ioctls().
> > > > I'd say you only opt in to such feature if you know what you are doing
> > > > and the user code takes care of specific cases like ioctl(), hence the
> > > > prctl() proposal even for the hwasan.
> > >
> > > I'm not sure such a dire view is warrented..
> > >
> > > The ioctl situation is not so bad, other than a few special cases,
> > > most drivers just take a 'void __user *' and pass it as an argument to
> > > some function that accepts a 'void __user *'. sparse et al verify
> > > this.
> > >
> > > As long as the core functions do the right thing the drivers will be
> > > OK.
> > >
> > > The only place things get dicy is if someone casts to unsigned long
> > > (ie for vma work) but I think that reflects that our driver facing
> > > APIs for VMAs are compatible with static analysis (ie I have no
> > > earthly idea why get_user_pages() accepts an unsigned long), not that
> > > this is too hard.
> >
> > If multiple people will care about this, perhaps we should try to
> > annotate types more explicitly in SYSCALL_DEFINEx() and ABI data
> > structures.
> >
> > For example, we could have a couple of mutually exclusive modifiers
> >
> > T __object *
> > T __vaddr * (or U __vaddr)
> >
> > In the first case the pointer points to an object (in the C sense)
> > that the call may dereference but not use for any other purpose.
>
> How would you use these two differently?
>
> So far the kernel has worked that __user should tag any pointer that
> is from userspace and then you can't do anything with it until you
> transform it into a kernel something
Ultimately it would be good to disallow casting __object pointers execpt
to compatible __object pointer types, and to make get_user etc. demand
__object.
__vaddr pointers / addresses would be freely castable, but not to
__object and so would not be dereferenceable even indirectly.
Or that's the general idea. Figuring out a sane set of rules that we
could actually check / enforce would require a bit of work.
(Whether the __vaddr base type is a pointer or an integer type is
probably moot, due to the restrictions we would place on the use of
these anyway.)
> > to tell static analysers the real type of pointers smuggled through
> > UAPI disguised as other types (*cough* KVM, etc.)
>
> Yes, that would help alot, we often have to pass pointers through a
> u64 in the uAPI, and there is no static checker support to make sure
> they are run through the u64_to_user_ptr() helper.
Agreed.
Cheers
---Dave
^ permalink raw reply
* Re: [PATCH v15 05/17] arms64: untag user pointers passed to memory syscalls
From: Catalin Marinas @ 2019-05-23 9:04 UTC (permalink / raw)
To: Evgenii Stepanov
Cc: Andrey Konovalov, Linux ARM, Linux Memory Management List, LKML,
amd-gfx, dri-devel, linux-rdma, linux-media, kvm,
open list:KERNEL SELFTEST FRAMEWORK, Vincenzo Frascino,
Will Deacon, Mark Rutland, Andrew Morton, Greg Kroah-Hartman,
Kees Cook, Yishai Hadas, Felix Kuehling, Alexander Deucher
In-Reply-To: <CAFKCwrjyP+x0JJy=qpBFsp4pub3He6UkvU0qnf1UOKt6W1LPRQ@mail.gmail.com>
On Wed, May 22, 2019 at 02:16:57PM -0700, Evgenii Stepanov wrote:
> On Wed, May 22, 2019 at 4:49 AM Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Mon, May 06, 2019 at 06:30:51PM +0200, Andrey Konovalov wrote:
> > > This patch is a part of a series that extends arm64 kernel ABI to allow to
> > > pass tagged user pointers (with the top byte set to something else other
> > > than 0x00) as syscall arguments.
> > >
> > > This patch allows tagged pointers to be passed to the following memory
> > > syscalls: brk, get_mempolicy, madvise, mbind, mincore, mlock, mlock2,
> > > mmap, mmap_pgoff, mprotect, mremap, msync, munlock, munmap,
> > > remap_file_pages, shmat and shmdt.
> > >
> > > This is done by untagging pointers passed to these syscalls in the
> > > prologues of their handlers.
> >
> > I'll go through them one by one to see if we can tighten the expected
> > ABI while having the MTE in mind.
> >
> > > diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c
> > > index b44065fb1616..933bb9f3d6ec 100644
> > > --- a/arch/arm64/kernel/sys.c
> > > +++ b/arch/arm64/kernel/sys.c
> > > @@ -35,10 +35,33 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> > > {
> > > if (offset_in_page(off) != 0)
> > > return -EINVAL;
> > > -
> > > + addr = untagged_addr(addr);
> > > return ksys_mmap_pgoff(addr, len, prot, flags, fd, off >> PAGE_SHIFT);
> > > }
> >
> > If user passes a tagged pointer to mmap() and the address is honoured
> > (or MAP_FIXED is given), what is the expected return pointer? Does it
> > need to be tagged with the value from the hint?
>
> For HWASan the most convenient would be to use the tag from the hint.
> But since in the TBI (not MTE) mode the kernel has no idea what
> meaning userspace assigns to pointer tags, perhaps it should not try
> to guess, and should return raw (zero-tagged) address instead.
Then, just to relax the ABI for hwasan, shall we simply disallow tagged
pointers on mmap() arguments? We can leave them in for
mremap(old_address), madvise().
> > With MTE, we may want to use this as a request for the default colour of
> > the mapped pages (still under discussion).
>
> I like this - and in that case it would make sense to return the
> pointer that can be immediately dereferenced without crashing the
> process, i.e. with the matching tag.
This came up from the Android investigation work where large memory
allocations (using mmap) could be more efficiently pre-tagged by the
kernel on page fault. Not sure about the implementation details yet.
--
Catalin
^ permalink raw reply
* Re: [PATCH v15 00/17] arm64: untag user pointers passed to the kernel
From: Catalin Marinas @ 2019-05-23 7:34 UTC (permalink / raw)
To: enh
Cc: Evgenii Stepanov, Kees Cook, Andrey Konovalov, Khalid Aziz,
Linux ARM, Linux Memory Management List, LKML, amd-gfx, dri-devel,
linux-rdma, linux-media, kvm, open list:KERNEL SELFTEST FRAMEWORK,
Vincenzo Frascino, Will Deacon, Mark Rutland, Andrew Morton,
Greg Kroah-Hartman, Yishai Hadas
In-Reply-To: <CAJgzZorUPzrXu0ysDdKwnqdvgWZJ9tqRjF-9_5CU_UV+c0bRCA@mail.gmail.com>
On Wed, May 22, 2019 at 04:09:31PM -0700, enh wrote:
> On Wed, May 22, 2019 at 4:03 PM Evgenii Stepanov <eugenis@google.com> wrote:
> > On Wed, May 22, 2019 at 1:47 PM Kees Cook <keescook@chromium.org> wrote:
> > > On Wed, May 22, 2019 at 05:35:27PM +0100, Catalin Marinas wrote:
> > > > I would also expect the C library or dynamic loader to check for the
> > > > presence of a HWCAP_MTE bit before starting to tag memory allocations,
> > > > otherwise it would get SIGILL on the first MTE instruction it tries to
> > > > execute.
> > >
> > > I've got the same question as Elliot: aren't MTE instructions just NOP
> > > to older CPUs? I.e. if the CPU (or kernel) don't support it, it just
> > > gets entirely ignored: checking is only needed to satisfy curiosity
> > > or behavioral expectations.
> >
> > MTE instructions are not NOP. Most of them have side effects (changing
> > register values, zeroing memory).
>
> no, i meant "they're encoded in a space that was previously no-ops, so
> running on MTE code on old hardware doesn't cause SIGILL".
It does result in SIGILL, there wasn't enough encoding left in the NOP
space for old/current CPU implementations (in hindsight, we should have
reserved a bigger NOP space).
As Evgenii said, the libc needs to be careful when tagging the heap as
it would cause a SIGILL if the HWCAP_MTE is not set. The standard
application doesn't need to be recompiled as it would not issue MTE
colouring instructions, just standard LDR/STR.
Stack tagging is problematic if you want to colour each frame
individually, the function prologue would need the non-NOP MTE
instructions. The best we can do here is just having the (thread) stacks
of different colours.
--
Catalin
^ permalink raw reply
* [PATCH 1/1] infiniband/mm: convert put_page() to put_user_page*()
From: john.hubbard @ 2019-05-23 7:25 UTC (permalink / raw)
To: Andrew Morton, linux-mm
Cc: Jason Gunthorpe, LKML, linux-rdma, linux-fsdevel, John Hubbard,
Doug Ledford, Mike Marciniszyn, Dennis Dalessandro,
Christian Benvenuti, Jan Kara, Jason Gunthorpe, Ira Weiny
In-Reply-To: <20190523072537.31940-1-jhubbard@nvidia.com>
From: John Hubbard <jhubbard@nvidia.com>
For infiniband code that retains pages via get_user_pages*(),
release those pages via the new put_user_page(), or
put_user_pages*(), instead of put_page()
This is a tiny part of the second step of fixing the problem described
in [1]. The steps are:
1) Provide put_user_page*() routines, intended to be used
for releasing pages that were pinned via get_user_pages*().
2) Convert all of the call sites for get_user_pages*(), to
invoke put_user_page*(), instead of put_page(). This involves dozens of
call sites, and will take some time.
3) After (2) is complete, use get_user_pages*() and put_user_page*() to
implement tracking of these pages. This tracking will be separate from
the existing struct page refcounting.
4) Use the tracking and identification of these pages, to implement
special handling (especially in writeback paths) when the pages are
backed by a filesystem. Again, [1] provides details as to why that is
desirable.
[1] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()"
Cc: Doug Ledford <dledford@redhat.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
Cc: Christian Benvenuti <benve@cisco.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Acked-by: Jason Gunthorpe <jgg@mellanox.com>
Tested-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
---
drivers/infiniband/core/umem.c | 7 ++++---
drivers/infiniband/core/umem_odp.c | 10 +++++-----
drivers/infiniband/hw/hfi1/user_pages.c | 11 ++++-------
drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++---
drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++++-------
drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +++---
drivers/infiniband/hw/usnic/usnic_uiom.c | 7 ++++---
7 files changed, 27 insertions(+), 31 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index e7ea819fcb11..673f0d240b3e 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -54,9 +54,10 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->sg_nents, 0) {
page = sg_page_iter_page(&sg_iter);
- if (!PageDirty(page) && umem->writable && dirty)
- set_page_dirty_lock(page);
- put_page(page);
+ if (umem->writable && dirty)
+ put_user_pages_dirty_lock(&page, 1);
+ else
+ put_user_page(page);
}
sg_free_table(&umem->sg_head);
diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
index f962b5bbfa40..17e46df3990a 100644
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
@@ -487,7 +487,7 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
* The function returns -EFAULT if the DMA mapping operation fails. It returns
* -EAGAIN if a concurrent invalidation prevents us from updating the page.
*
- * The page is released via put_page even if the operation failed. For
+ * The page is released via put_user_page even if the operation failed. For
* on-demand pinning, the page is released whenever it isn't stored in the
* umem.
*/
@@ -536,7 +536,7 @@ static int ib_umem_odp_map_dma_single_page(
}
out:
- put_page(page);
+ put_user_page(page);
if (remove_existing_mapping) {
ib_umem_notifier_start_account(umem_odp);
@@ -659,7 +659,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
ret = -EFAULT;
break;
}
- put_page(local_page_list[j]);
+ put_user_page(local_page_list[j]);
continue;
}
@@ -686,8 +686,8 @@ int ib_umem_odp_map_dma_pages(struct ib_umem_odp *umem_odp, u64 user_virt,
* ib_umem_odp_map_dma_single_page().
*/
if (npages - (j + 1) > 0)
- release_pages(&local_page_list[j+1],
- npages - (j + 1));
+ put_user_pages(&local_page_list[j+1],
+ npages - (j + 1));
break;
}
}
diff --git a/drivers/infiniband/hw/hfi1/user_pages.c b/drivers/infiniband/hw/hfi1/user_pages.c
index 02eee8eff1db..b89a9b9aef7a 100644
--- a/drivers/infiniband/hw/hfi1/user_pages.c
+++ b/drivers/infiniband/hw/hfi1/user_pages.c
@@ -118,13 +118,10 @@ int hfi1_acquire_user_pages(struct mm_struct *mm, unsigned long vaddr, size_t np
void hfi1_release_user_pages(struct mm_struct *mm, struct page **p,
size_t npages, bool dirty)
{
- size_t i;
-
- for (i = 0; i < npages; i++) {
- if (dirty)
- set_page_dirty_lock(p[i]);
- put_page(p[i]);
- }
+ if (dirty)
+ put_user_pages_dirty_lock(p, npages);
+ else
+ put_user_pages(p, npages);
if (mm) { /* during close after signal, mm can be NULL */
atomic64_sub(npages, &mm->pinned_vm);
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 8ff0e90d7564..edccfd6e178f 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -482,7 +482,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
if (ret < 0) {
- put_page(pages[0]);
+ put_user_page(pages[0]);
goto out;
}
@@ -490,7 +490,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
mthca_uarc_virt(dev, uar, i));
if (ret) {
pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
- put_page(sg_page(&db_tab->page[i].mem));
+ put_user_page(sg_page(&db_tab->page[i].mem));
goto out;
}
@@ -556,7 +556,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
if (db_tab->page[i].uvirt) {
mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1);
pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
- put_page(sg_page(&db_tab->page[i].mem));
+ put_user_page(sg_page(&db_tab->page[i].mem));
}
}
diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c
index f712fb7fa82f..bfbfbb7e0ff4 100644
--- a/drivers/infiniband/hw/qib/qib_user_pages.c
+++ b/drivers/infiniband/hw/qib/qib_user_pages.c
@@ -40,13 +40,10 @@
static void __qib_release_user_pages(struct page **p, size_t num_pages,
int dirty)
{
- size_t i;
-
- for (i = 0; i < num_pages; i++) {
- if (dirty)
- set_page_dirty_lock(p[i]);
- put_page(p[i]);
- }
+ if (dirty)
+ put_user_pages_dirty_lock(p, num_pages);
+ else
+ put_user_pages(p, num_pages);
}
/**
diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c b/drivers/infiniband/hw/qib/qib_user_sdma.c
index 0c204776263f..ac5bdb02144f 100644
--- a/drivers/infiniband/hw/qib/qib_user_sdma.c
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
@@ -317,7 +317,7 @@ static int qib_user_sdma_page_to_frags(const struct qib_devdata *dd,
* the caller can ignore this page.
*/
if (put) {
- put_page(page);
+ put_user_page(page);
} else {
/* coalesce case */
kunmap(page);
@@ -631,7 +631,7 @@ static void qib_user_sdma_free_pkt_frag(struct device *dev,
kunmap(pkt->addr[i].page);
if (pkt->addr[i].put_page)
- put_page(pkt->addr[i].page);
+ put_user_page(pkt->addr[i].page);
else
__free_page(pkt->addr[i].page);
} else if (pkt->addr[i].kvaddr) {
@@ -706,7 +706,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd,
/* if error, return all pages not managed by pkt */
free_pages:
while (i < j)
- put_page(pages[i++]);
+ put_user_page(pages[i++]);
done:
return ret;
diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
index e312f522a66d..0b0237d41613 100644
--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
+++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
@@ -75,9 +75,10 @@ static void usnic_uiom_put_pages(struct list_head *chunk_list, int dirty)
for_each_sg(chunk->page_list, sg, chunk->nents, i) {
page = sg_page(sg);
pa = sg_phys(sg);
- if (!PageDirty(page) && dirty)
- set_page_dirty_lock(page);
- put_page(page);
+ if (dirty)
+ put_user_pages_dirty_lock(&page, 1);
+ else
+ put_user_page(page);
usnic_dbg("pa: %pa\n", &pa);
}
kfree(chunk);
--
2.21.0
^ permalink raw reply related
* [PATCH 0/1] infiniband/mm: convert put_page() to put_user_page*()
From: john.hubbard @ 2019-05-23 7:25 UTC (permalink / raw)
To: Andrew Morton, linux-mm
Cc: Jason Gunthorpe, LKML, linux-rdma, linux-fsdevel, John Hubbard,
Doug Ledford, Mike Marciniszyn, Dennis Dalessandro,
Christian Benvenuti, Jan Kara, Jason Gunthorpe, Ira Weiny
From: John Hubbard <jhubbard@nvidia.com>
Hi Jason and all,
IIUC, now that we have the put_user_pages() merged in to linux.git, we can
start sending up the callsite conversions via different subsystem
maintainer trees. Here's one for linux-rdma.
I've left the various Reviewed-by: and Tested-by: tags on here, even
though it's been through a few rebases.
If anyone has hardware, it would be good to get a real test of this.
thanks,
--
John Hubbard
NVIDIA
Cc: Doug Ledford <dledford@redhat.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Mike Marciniszyn <mike.marciniszyn@intel.com>
Cc: Dennis Dalessandro <dennis.dalessandro@intel.com>
Cc: Christian Benvenuti <benve@cisco.com>
Cc: Jan Kara <jack@suse.cz>
Cc: Jason Gunthorpe <jgg@mellanox.com>
Cc: Ira Weiny <ira.weiny@intel.com>
John Hubbard (1):
infiniband/mm: convert put_page() to put_user_page*()
drivers/infiniband/core/umem.c | 7 ++++---
drivers/infiniband/core/umem_odp.c | 10 +++++-----
drivers/infiniband/hw/hfi1/user_pages.c | 11 ++++-------
drivers/infiniband/hw/mthca/mthca_memfree.c | 6 +++---
drivers/infiniband/hw/qib/qib_user_pages.c | 11 ++++-------
drivers/infiniband/hw/qib/qib_user_sdma.c | 6 +++---
drivers/infiniband/hw/usnic/usnic_uiom.c | 7 ++++---
7 files changed, 27 insertions(+), 31 deletions(-)
--
2.21.0
^ permalink raw reply
* Re: [PATCH] RDMA/mlx5: Use DIV_ROUND_UP_ULL macro to allow 32 bit to build
From: Michal Kubecek @ 2019-05-23 6:58 UTC (permalink / raw)
To: Steven Rostedt
Cc: LKML, Leon Romanovsky, Doug Ledford, Jason Gunthorpe, linux-rdma,
Linus Torvalds
In-Reply-To: <20190522145450.25ff483d@gandalf.local.home>
On Wed, May 22, 2019 at 02:54:50PM -0400, Steven Rostedt wrote:
>
> From: Steven Rostedt (VMware) <rostedt@goodmis.org>
>
> When testing 32 bit x86, my build failed with:
>
> ERROR: "__udivdi3" [drivers/infiniband/hw/mlx5/mlx5_ib.ko] undefined!
>
> It appears that a few non-ULL roundup() calls were made, which uses a
> normal division against a 64 bit number. This is fine for x86_64, but
> on 32 bit x86, it causes the compiler to look for a helper function
> __udivdi3, which we do not have in the kernel, and thus fails to build.
>
> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> ---
...
> diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
> index abac70ad5c7c..40d4c5f7ea43 100644
> --- a/drivers/infiniband/hw/mlx5/main.c
> +++ b/drivers/infiniband/hw/mlx5/main.c
> @@ -2344,7 +2344,7 @@ static int handle_alloc_dm_sw_icm(struct ib_ucontext *ctx,
> /* Allocation size must a multiple of the basic block size
> * and a power of 2.
> */
> - act_size = roundup(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
> + act_size = DIV_ROUND_UP_ULL(attr->length, MLX5_SW_ICM_BLOCK_SIZE(dm_db->dev));
> act_size = roundup_pow_of_two(act_size);
>
> dm->size = act_size;
This seems wrong: roundup() rounds up to a multiple of second argument
but DIV_ROUND_UP_ULL() would divide with rounding up.
Michal Kubecek
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox