dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel.vetter@ffwll.ch>
To: John Hubbard <jhubbard@nvidia.com>
Cc: linux-samsung-soc <linux-samsung-soc@vger.kernel.org>,
	"Jan Kara" <jack@suse.cz>, "Kees Cook" <keescook@chromium.org>,
	"KVM list" <kvm@vger.kernel.org>,
	"Jason Gunthorpe" <jgg@ziepe.ca>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"David Hildenbrand" <david@redhat.com>,
	LKML <linux-kernel@vger.kernel.org>,
	"DRI Development" <dri-devel@lists.freedesktop.org>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	"Linux MM" <linux-mm@kvack.org>,
	"Jérôme Glisse" <jglisse@redhat.com>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Daniel Vetter" <daniel.vetter@intel.com>,
	"Dan Williams" <dan.j.williams@intel.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Linux ARM" <linux-arm-kernel@lists.infradead.org>,
	"open list:DMA BUFFER SHARING FRAMEWORK"
	<linux-media@vger.kernel.org>
Subject: Re: [PATCH v5 13/15] resource: Move devmem revoke code to resource framework
Date: Sat, 31 Oct 2020 15:40:35 +0100	[thread overview]
Message-ID: <CAKMK7uF=N1hGSnFscaX0PGxWVkrUoYK-H+gnBhYkG1KU_KvVEg@mail.gmail.com> (raw)
In-Reply-To: <787f2914-5777-4703-4bee-68c4c3742817@nvidia.com>

On Sat, Oct 31, 2020 at 7:36 AM John Hubbard <jhubbard@nvidia.com> wrote:
>
> On 10/30/20 3:08 AM, Daniel Vetter wrote:
> > We want all iomem mmaps to consistently revoke ptes when the kernel
> > takes over and CONFIG_IO_STRICT_DEVMEM is enabled. This includes the
> > pci bar mmaps available through procfs and sysfs, which currently do
> > not revoke mappings.
> >
> > To prepare for this, move the code from the /dev/kmem driver to
> > kernel/resource.c.
>
> This seems like it's doing a lot more than just code movement, right?
> Should we list some of that here?

It was meant to be just moving code, but then the inevitable bikeshed
showed up and I forgot to update the commit message properly. Will fix
that.

> Also, I'm seeing a crash due to this commit. More below:

Uh that's not good.
>
> >
> > Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
> > Cc: Jason Gunthorpe <jgg@ziepe.ca>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Dan Williams <dan.j.williams@intel.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: John Hubbard <jhubbard@nvidia.com>
> > Cc: Jérôme Glisse <jglisse@redhat.com>
> > Cc: Jan Kara <jack@suse.cz>
> > Cc: Dan Williams <dan.j.williams@intel.com>
> > Cc: linux-mm@kvack.org
> > Cc: linux-arm-kernel@lists.infradead.org
> > Cc: linux-samsung-soc@vger.kernel.org
> > Cc: linux-media@vger.kernel.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
> > Cc: David Hildenbrand <david@redhat.com>
> > Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> > --
> > v3:
> > - add barrier for consistency and document why we don't have to check
> >    for NULL (Jason)
> > v4
> > - Adjust comments to reflect the general nature of this iomem revoke
> >    code now (Dan)
> > ---
> >   drivers/char/mem.c     |  85 +---------------------------------
> >   include/linux/ioport.h |   6 +--
> >   kernel/resource.c      | 101 ++++++++++++++++++++++++++++++++++++++++-
> >   3 files changed, 102 insertions(+), 90 deletions(-)
> >
> > diff --git a/drivers/char/mem.c b/drivers/char/mem.c
> > index 7dcf9e4ea79d..43c871dc7477 100644
> > --- a/drivers/char/mem.c
> > +++ b/drivers/char/mem.c
> > @@ -31,9 +31,6 @@
> >   #include <linux/uio.h>
> >   #include <linux/uaccess.h>
> >   #include <linux/security.h>
> > -#include <linux/pseudo_fs.h>
> > -#include <uapi/linux/magic.h>
> > -#include <linux/mount.h>
> >
> >   #ifdef CONFIG_IA64
> >   # include <linux/efi.h>
> > @@ -836,42 +833,6 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
> >       return ret;
> >   }
> >
> > -static struct inode *devmem_inode;
> > -
> > -#ifdef CONFIG_IO_STRICT_DEVMEM
> > -void revoke_devmem(struct resource *res)
> > -{
> > -     /* pairs with smp_store_release() in devmem_init_inode() */
> > -     struct inode *inode = smp_load_acquire(&devmem_inode);
> > -
> > -     /*
> > -      * Check that the initialization has completed. Losing the race
> > -      * is ok because it means drivers are claiming resources before
> > -      * the fs_initcall level of init and prevent /dev/mem from
> > -      * establishing mappings.
> > -      */
> > -     if (!inode)
> > -             return;
> > -
> > -     /*
> > -      * The expectation is that the driver has successfully marked
> > -      * the resource busy by this point, so devmem_is_allowed()
> > -      * should start returning false, however for performance this
> > -      * does not iterate the entire resource range.
> > -      */
> > -     if (devmem_is_allowed(PHYS_PFN(res->start)) &&
> > -         devmem_is_allowed(PHYS_PFN(res->end))) {
> > -             /*
> > -              * *cringe* iomem=relaxed says "go ahead, what's the
> > -              * worst that can happen?"
> > -              */
> > -             return;
> > -     }
> > -
> > -     unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1);
> > -}
> > -#endif
> > -
> >   static int open_port(struct inode *inode, struct file *filp)
> >   {
> >       int rc;
> > @@ -891,7 +852,7 @@ static int open_port(struct inode *inode, struct file *filp)
> >        * revocations when drivers want to take over a /dev/mem mapped
> >        * range.
> >        */
> > -     filp->f_mapping = inode->i_mapping;
> > +     filp->f_mapping = iomem_get_mapping();
>
>
> The problem is that iomem_get_mapping() returns NULL for the !CONFIG_IO_STRICT_DEVMEM
> case. And then we have pre-existing fs code that expects to go "up and over", like this:
>
>
> static int do_dentry_open(struct file *f,
>                           struct inode *inode,
>                           int (*open)(struct inode *, struct file *))
> {
> ...
>
>         file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
>
> ...and it crashes on that line fairly early in bootup.
>
> Not sure what to suggest for this patch, but wanted to get this report out at least.

Old code seems to have worked by always setting up the inode (we still
do that) and always setting it (we don't do that anymore), just not
revoking the ptes when the Kconfig is not set. I'll fix that up and
remove the behaviour change here.
-Daniel

> thanks,
> --
> John Hubbard
> NVIDIA
>
> >
> >       return 0;
> >   }
> > @@ -1023,48 +984,6 @@ static char *mem_devnode(struct device *dev, umode_t *mode)
> >
> >   static struct class *mem_class;
> >
> > -static int devmem_fs_init_fs_context(struct fs_context *fc)
> > -{
> > -     return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM;
> > -}
> > -
> > -static struct file_system_type devmem_fs_type = {
> > -     .name           = "devmem",
> > -     .owner          = THIS_MODULE,
> > -     .init_fs_context = devmem_fs_init_fs_context,
> > -     .kill_sb        = kill_anon_super,
> > -};
> > -
> > -static int devmem_init_inode(void)
> > -{
> > -     static struct vfsmount *devmem_vfs_mount;
> > -     static int devmem_fs_cnt;
> > -     struct inode *inode;
> > -     int rc;
> > -
> > -     rc = simple_pin_fs(&devmem_fs_type, &devmem_vfs_mount, &devmem_fs_cnt);
> > -     if (rc < 0) {
> > -             pr_err("Cannot mount /dev/mem pseudo filesystem: %d\n", rc);
> > -             return rc;
> > -     }
> > -
> > -     inode = alloc_anon_inode(devmem_vfs_mount->mnt_sb);
> > -     if (IS_ERR(inode)) {
> > -             rc = PTR_ERR(inode);
> > -             pr_err("Cannot allocate inode for /dev/mem: %d\n", rc);
> > -             simple_release_fs(&devmem_vfs_mount, &devmem_fs_cnt);
> > -             return rc;
> > -     }
> > -
> > -     /*
> > -      * Publish /dev/mem initialized.
> > -      * Pairs with smp_load_acquire() in revoke_devmem().
> > -      */
> > -     smp_store_release(&devmem_inode, inode);
> > -
> > -     return 0;
> > -}
> > -
> >   static int __init chr_dev_init(void)
> >   {
> >       int minor;
> > @@ -1086,8 +1005,6 @@ static int __init chr_dev_init(void)
> >                */
> >               if ((minor == DEVPORT_MINOR) && !arch_has_dev_port())
> >                       continue;
> > -             if ((minor == DEVMEM_MINOR) && devmem_init_inode() != 0)
> > -                     continue;
> >
> >               device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
> >                             NULL, devlist[minor].name);
> > diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> > index 5135d4b86cd6..02a5466245c0 100644
> > --- a/include/linux/ioport.h
> > +++ b/include/linux/ioport.h
> > @@ -307,11 +307,7 @@ struct resource *devm_request_free_mem_region(struct device *dev,
> >   struct resource *request_free_mem_region(struct resource *base,
> >               unsigned long size, const char *name);
> >
> > -#ifdef CONFIG_IO_STRICT_DEVMEM
> > -void revoke_devmem(struct resource *res);
> > -#else
> > -static inline void revoke_devmem(struct resource *res) { };
> > -#endif
> > +extern struct address_space *iomem_get_mapping(void);
> >
> >   #endif /* __ASSEMBLY__ */
> >   #endif      /* _LINUX_IOPORT_H */
> > diff --git a/kernel/resource.c b/kernel/resource.c
> > index 3ae2f56cc79d..5ecc3187fe2d 100644
> > --- a/kernel/resource.c
> > +++ b/kernel/resource.c
> > @@ -18,12 +18,15 @@
> >   #include <linux/spinlock.h>
> >   #include <linux/fs.h>
> >   #include <linux/proc_fs.h>
> > +#include <linux/pseudo_fs.h>
> >   #include <linux/sched.h>
> >   #include <linux/seq_file.h>
> >   #include <linux/device.h>
> >   #include <linux/pfn.h>
> >   #include <linux/mm.h>
> > +#include <linux/mount.h>
> >   #include <linux/resource_ext.h>
> > +#include <uapi/linux/magic.h>
> >   #include <asm/io.h>
> >
> >
> > @@ -1115,6 +1118,58 @@ resource_size_t resource_alignment(struct resource *res)
> >
> >   static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
> >
> > +static struct inode *iomem_inode;
> > +
> > +#ifdef CONFIG_IO_STRICT_DEVMEM
> > +static void revoke_iomem(struct resource *res)
> > +{
> > +     /* pairs with smp_store_release() in iomem_init_inode() */
> > +     struct inode *inode = smp_load_acquire(&iomem_inode);
> > +
> > +     /*
> > +      * Check that the initialization has completed. Losing the race
> > +      * is ok because it means drivers are claiming resources before
> > +      * the fs_initcall level of init and prevent iomem_get_mapping users
> > +      * from establishing mappings.
> > +      */
> > +     if (!inode)
> > +             return;
> > +
> > +     /*
> > +      * The expectation is that the driver has successfully marked
> > +      * the resource busy by this point, so devmem_is_allowed()
> > +      * should start returning false, however for performance this
> > +      * does not iterate the entire resource range.
> > +      */
> > +     if (devmem_is_allowed(PHYS_PFN(res->start)) &&
> > +         devmem_is_allowed(PHYS_PFN(res->end))) {
> > +             /*
> > +              * *cringe* iomem=relaxed says "go ahead, what's the
> > +              * worst that can happen?"
> > +              */
> > +             return;
> > +     }
> > +
> > +     unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1);
> > +}
> > +struct address_space *iomem_get_mapping(void)
> > +{
> > +     /*
> > +      * This function is only called from file open paths, hence guaranteed
> > +      * that fs_initcalls have completed and no need to check for NULL. But
> > +      * since revoke_iomem can be called before the initcall we still need
> > +      * the barrier to appease checkers.
> > +      */
> > +     return smp_load_acquire(&iomem_inode)->i_mapping;
> > +}
> > +#else
> > +static void revoke_iomem(struct resource *res) {}
> > +struct address_space *iomem_get_mapping(void)
> > +{
> > +     return NULL;
> > +}
> > +#endif
> > +
> >   /**
> >    * __request_region - create a new busy resource region
> >    * @parent: parent resource descriptor
> > @@ -1182,7 +1237,7 @@ struct resource * __request_region(struct resource *parent,
> >       write_unlock(&resource_lock);
> >
> >       if (res && orig_parent == &iomem_resource)
> > -             revoke_devmem(res);
> > +             revoke_iomem(res);
> >
> >       return res;
> >   }
> > @@ -1782,4 +1837,48 @@ static int __init strict_iomem(char *str)
> >       return 1;
> >   }
> >
> > +static int iomem_fs_init_fs_context(struct fs_context *fc)
> > +{
> > +     return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM;
> > +}
> > +
> > +static struct file_system_type iomem_fs_type = {
> > +     .name           = "iomem",
> > +     .owner          = THIS_MODULE,
> > +     .init_fs_context = iomem_fs_init_fs_context,
> > +     .kill_sb        = kill_anon_super,
> > +};
> > +
> > +static int __init iomem_init_inode(void)
> > +{
> > +     static struct vfsmount *iomem_vfs_mount;
> > +     static int iomem_fs_cnt;
> > +     struct inode *inode;
> > +     int rc;
> > +
> > +     rc = simple_pin_fs(&iomem_fs_type, &iomem_vfs_mount, &iomem_fs_cnt);
> > +     if (rc < 0) {
> > +             pr_err("Cannot mount iomem pseudo filesystem: %d\n", rc);
> > +             return rc;
> > +     }
> > +
> > +     inode = alloc_anon_inode(iomem_vfs_mount->mnt_sb);
> > +     if (IS_ERR(inode)) {
> > +             rc = PTR_ERR(inode);
> > +             pr_err("Cannot allocate inode for iomem: %d\n", rc);
> > +             simple_release_fs(&iomem_vfs_mount, &iomem_fs_cnt);
> > +             return rc;
> > +     }
> > +
> > +     /*
> > +      * Publish iomem revocation inode initialized.
> > +      * Pairs with smp_load_acquire() in revoke_iomem().
> > +      */
> > +     smp_store_release(&iomem_inode, inode);
> > +
> > +     return 0;
> > +}
> > +
> > +fs_initcall(iomem_init_inode);
> > +
> >   __setup("iomem=", strict_iomem);
> >
>
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2020-10-31 14:40 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-30 10:08 [PATCH v5 00/15] follow_pfn and other iomap races Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 01/15] drm/exynos: Stop using frame_vector helpers Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 02/15] drm/exynos: Use FOLL_LONGTERM for g2d cmdlists Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 03/15] misc/habana: Stop using frame_vector helpers Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 04/15] misc/habana: Use FOLL_LONGTERM for userptr Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 05/15] mm/frame-vector: Use FOLL_LONGTERM Daniel Vetter
2020-10-30 14:11   ` Tomasz Figa
2020-10-30 14:37     ` Daniel Vetter
2020-11-02 18:19       ` Tomasz Figa
2020-10-31  2:55   ` John Hubbard
2020-10-31 14:45     ` Daniel Vetter
2020-11-01  5:22       ` John Hubbard
2020-11-01 10:30         ` Daniel Vetter
2020-11-01 21:13           ` John Hubbard
2020-11-01 22:50             ` Daniel Vetter
2020-11-04 14:00               ` Jason Gunthorpe
2020-11-04 15:54                 ` Daniel Vetter
     [not found]                   ` <20201104162125.GA13007@infradead.org>
2020-11-04 16:26                     ` Daniel Vetter
     [not found]                       ` <20201104163758.GA17425@infradead.org>
     [not found]                         ` <20201104164119.GA18218@infradead.org>
2020-11-04 18:17                           ` Jason Gunthorpe
2020-11-04 18:44                             ` John Hubbard
2020-11-04 19:02                               ` Jason Gunthorpe
2020-11-05  9:25                               ` Daniel Vetter
2020-11-05 12:49                                 ` Jason Gunthorpe
2020-11-06  4:08                                   ` John Hubbard
2020-11-06 10:01                                     ` Daniel Vetter
2020-11-06 10:27                                       ` Daniel Vetter
2020-11-06 12:55                                         ` Jason Gunthorpe
2020-11-09  8:44                                           ` Thomas Hellström
2020-11-09 20:19                                             ` Jason Gunthorpe
2020-11-06 12:58                                       ` Jason Gunthorpe
2020-10-30 10:08 ` [PATCH v5 06/15] media: videobuf2: Move frame_vector into media subsystem Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 07/15] mm: Close race in generic_access_phys Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 08/15] mm: Add unsafe_follow_pfn Daniel Vetter
     [not found]   ` <20201102072931.GA16419@infradead.org>
2020-11-02 12:56     ` Daniel Vetter
2020-11-02 13:01       ` Jason Gunthorpe
2020-11-02 13:23         ` Daniel Vetter
2020-11-02 15:52           ` Jason Gunthorpe
2020-11-02 16:42             ` Daniel Vetter
2020-11-02 17:16               ` Jason Gunthorpe
2020-10-30 10:08 ` [PATCH v5 09/15] media/videbuf1|2: Mark follow_pfn usage as unsafe Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 10/15] vfio/type1: Mark follow_pfn " Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 11/15] PCI: Obey iomem restrictions for procfs mmap Daniel Vetter
2020-11-03 21:28   ` Bjorn Helgaas
2020-11-03 22:09     ` Dan Williams
2020-11-04  8:44       ` Daniel Vetter
2020-11-04 16:50         ` Bjorn Helgaas
2020-11-04 20:12           ` Dan Williams
2020-11-05  9:34             ` Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 12/15] /dev/mem: Only set filp->f_mapping Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 13/15] resource: Move devmem revoke code to resource framework Daniel Vetter
2020-10-31  6:36   ` John Hubbard
2020-10-31 14:40     ` Daniel Vetter [this message]
2020-11-03  6:06   ` [resource] 22b17dc667: Kernel panic - not syncing: Fatal exception lkp
2020-11-03  6:15     ` John Hubbard
2020-11-03 10:10       ` Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 14/15] sysfs: Support zapping of binary attr mmaps Daniel Vetter
2020-10-30 10:08 ` [PATCH v5 15/15] PCI: Revoke mappings like devmem Daniel Vetter
2020-10-30 19:22   ` Dan Williams
2020-11-03 21:30   ` Bjorn Helgaas

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='CAKMK7uF=N1hGSnFscaX0PGxWVkrUoYK-H+gnBhYkG1KU_KvVEg@mail.gmail.com' \
    --to=daniel.vetter@ffwll.ch \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=dan.j.williams@intel.com \
    --cc=daniel.vetter@intel.com \
    --cc=david@redhat.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=jgg@ziepe.ca \
    --cc=jglisse@redhat.com \
    --cc=jhubbard@nvidia.com \
    --cc=keescook@chromium.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=rafael.j.wysocki@intel.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;
as well as URLs for NNTP newsgroup(s).