All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Rutland <mark.rutland@arm.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andreas Gruenbacher <agruenba@redhat.com>,
	Josef Bacik <josef@toxicpanda.com>,
	David Sterba <dsterba@suse.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Andrew Morton <akpm@linux-foundation.org>,
	Will Deacon <will@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v2 3/4] arm64: Add support for user sub-page fault probing
Date: Wed, 1 Dec 2021 20:29:06 +0000	[thread overview]
Message-ID: <YafbEpoiFB4emaPW@FVFF77S0Q05N> (raw)
In-Reply-To: <20211201193750.2097885-4-catalin.marinas@arm.com>

Hi Catalin,

On Wed, Dec 01, 2021 at 07:37:49PM +0000, Catalin Marinas wrote:
> With MTE, even if the pte allows an access, a mismatched tag somewhere
> within a page can still cause a fault. Select ARCH_HAS_SUBPAGE_FAULTS if
> MTE is enabled and implement the probe_subpage_*() functions. Note that
> get_user() is sufficient for the writeable checks since the same tag
> mismatch fault would be triggered by a read.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/uaccess.h | 59 ++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..dff89fd0d817 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1777,6 +1777,7 @@ config ARM64_MTE
>  	depends on AS_HAS_LSE_ATOMICS
>  	# Required for tag checking in the uaccess routines
>  	depends on ARM64_PAN
> +	select ARCH_HAS_SUBPAGE_FAULTS
>  	select ARCH_USES_HIGH_VMA_FLAGS
>  	help
>  	  Memory Tagging (part of the ARMv8.5 Extensions) provides
> diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
> index 6e2e0b7031ab..bcbd24b97917 100644
> --- a/arch/arm64/include/asm/uaccess.h
> +++ b/arch/arm64/include/asm/uaccess.h
> @@ -445,4 +445,63 @@ static inline int __copy_from_user_flushcache(void *dst, const void __user *src,
>  }
>  #endif
>  
> +#ifdef CONFIG_ARCH_HAS_SUBPAGE_FAULTS
> +
> +/*
> + * Return 0 on success, the number of bytes not accessed otherwise.
> + */
> +static inline size_t __mte_probe_user_range(const char __user *uaddr,
> +					    size_t size, bool skip_first)
> +{
> +	const char __user *end = uaddr + size;
> +	int err = 0;
> +	char val;
> +
> +	uaddr = PTR_ALIGN_DOWN(uaddr, MTE_GRANULE_SIZE);
> +	if (skip_first)
> +		uaddr += MTE_GRANULE_SIZE;

Do we need the skipping for a functional reason, or is that an optimization?

From the comments in probe_subpage_writeable() and
probe_subpage_safe_writeable() I wasn't sure if the skipping was because we
*don't need to* check the first granule, or because we *must not* check the
first granule.

> +	while (uaddr < end) {
> +		/*
> +		 * A read is sufficient for MTE, the caller should have probed
> +		 * for the pte write permission if required.
> +		 */
> +		__raw_get_user(val, uaddr, err);
> +		if (err)
> +			return end - uaddr;
> +		uaddr += MTE_GRANULE_SIZE;
> +	}

I think we may need to account for the residue from PTR_ALIGN_DOWN(), or we can
report more bytes not copied than was passed in `size` in the first place,
which I think might confused some callers.

Consider MTE_GRANULE_SIZE is 16, uaddr is 31, and size is 1 (so end is 32). We
align uaddr down to 16, and if we fail the first access we return (32 - 16),
i.e. 16.

Thanks,
Mark.

> +	(void)val;
> +
> +	return 0;
> +}
> +
> +static inline size_t probe_subpage_writeable(const void __user *uaddr,
> +					     size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* first put_user() done in the caller */
> +	return __mte_probe_user_range(uaddr, size, true);
> +}
> +
> +static inline size_t probe_subpage_safe_writeable(const void __user *uaddr,
> +						  size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* the caller used GUP, don't skip the first granule */
> +	return __mte_probe_user_range(uaddr, size, false);
> +}
> +
> +static inline size_t probe_subpage_readable(const void __user *uaddr,
> +					    size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* first get_user() done in the caller */
> +	return __mte_probe_user_range(uaddr, size, true);
> +}
> +
> +#endif /* CONFIG_ARCH_HAS_SUBPAGE_FAULTS */
> +
>  #endif /* __ASM_UACCESS_H */

WARNING: multiple messages have this Message-ID (diff)
From: Mark Rutland <mark.rutland@arm.com>
To: Catalin Marinas <catalin.marinas@arm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andreas Gruenbacher <agruenba@redhat.com>,
	Josef Bacik <josef@toxicpanda.com>,
	David Sterba <dsterba@suse.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Andrew Morton <akpm@linux-foundation.org>,
	Will Deacon <will@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-btrfs@vger.kernel.org
Subject: Re: [PATCH v2 3/4] arm64: Add support for user sub-page fault probing
Date: Wed, 1 Dec 2021 20:29:06 +0000	[thread overview]
Message-ID: <YafbEpoiFB4emaPW@FVFF77S0Q05N> (raw)
In-Reply-To: <20211201193750.2097885-4-catalin.marinas@arm.com>

Hi Catalin,

On Wed, Dec 01, 2021 at 07:37:49PM +0000, Catalin Marinas wrote:
> With MTE, even if the pte allows an access, a mismatched tag somewhere
> within a page can still cause a fault. Select ARCH_HAS_SUBPAGE_FAULTS if
> MTE is enabled and implement the probe_subpage_*() functions. Note that
> get_user() is sufficient for the writeable checks since the same tag
> mismatch fault would be triggered by a read.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm64/Kconfig               |  1 +
>  arch/arm64/include/asm/uaccess.h | 59 ++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..dff89fd0d817 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1777,6 +1777,7 @@ config ARM64_MTE
>  	depends on AS_HAS_LSE_ATOMICS
>  	# Required for tag checking in the uaccess routines
>  	depends on ARM64_PAN
> +	select ARCH_HAS_SUBPAGE_FAULTS
>  	select ARCH_USES_HIGH_VMA_FLAGS
>  	help
>  	  Memory Tagging (part of the ARMv8.5 Extensions) provides
> diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
> index 6e2e0b7031ab..bcbd24b97917 100644
> --- a/arch/arm64/include/asm/uaccess.h
> +++ b/arch/arm64/include/asm/uaccess.h
> @@ -445,4 +445,63 @@ static inline int __copy_from_user_flushcache(void *dst, const void __user *src,
>  }
>  #endif
>  
> +#ifdef CONFIG_ARCH_HAS_SUBPAGE_FAULTS
> +
> +/*
> + * Return 0 on success, the number of bytes not accessed otherwise.
> + */
> +static inline size_t __mte_probe_user_range(const char __user *uaddr,
> +					    size_t size, bool skip_first)
> +{
> +	const char __user *end = uaddr + size;
> +	int err = 0;
> +	char val;
> +
> +	uaddr = PTR_ALIGN_DOWN(uaddr, MTE_GRANULE_SIZE);
> +	if (skip_first)
> +		uaddr += MTE_GRANULE_SIZE;

Do we need the skipping for a functional reason, or is that an optimization?

From the comments in probe_subpage_writeable() and
probe_subpage_safe_writeable() I wasn't sure if the skipping was because we
*don't need to* check the first granule, or because we *must not* check the
first granule.

> +	while (uaddr < end) {
> +		/*
> +		 * A read is sufficient for MTE, the caller should have probed
> +		 * for the pte write permission if required.
> +		 */
> +		__raw_get_user(val, uaddr, err);
> +		if (err)
> +			return end - uaddr;
> +		uaddr += MTE_GRANULE_SIZE;
> +	}

I think we may need to account for the residue from PTR_ALIGN_DOWN(), or we can
report more bytes not copied than was passed in `size` in the first place,
which I think might confused some callers.

Consider MTE_GRANULE_SIZE is 16, uaddr is 31, and size is 1 (so end is 32). We
align uaddr down to 16, and if we fail the first access we return (32 - 16),
i.e. 16.

Thanks,
Mark.

> +	(void)val;
> +
> +	return 0;
> +}
> +
> +static inline size_t probe_subpage_writeable(const void __user *uaddr,
> +					     size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* first put_user() done in the caller */
> +	return __mte_probe_user_range(uaddr, size, true);
> +}
> +
> +static inline size_t probe_subpage_safe_writeable(const void __user *uaddr,
> +						  size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* the caller used GUP, don't skip the first granule */
> +	return __mte_probe_user_range(uaddr, size, false);
> +}
> +
> +static inline size_t probe_subpage_readable(const void __user *uaddr,
> +					    size_t size)
> +{
> +	if (!system_supports_mte())
> +		return 0;
> +	/* first get_user() done in the caller */
> +	return __mte_probe_user_range(uaddr, size, true);
> +}
> +
> +#endif /* CONFIG_ARCH_HAS_SUBPAGE_FAULTS */
> +
>  #endif /* __ASM_UACCESS_H */

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-12-01 20:29 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-01 19:37 [PATCH v2 0/4] Avoid live-lock in fault-in+uaccess loops with sub-page faults Catalin Marinas
2021-12-01 19:37 ` Catalin Marinas
2021-12-01 19:37 ` [PATCH v2 1/4] mm: Introduce a 'min_size' argument to fault_in_*() Catalin Marinas
2021-12-01 19:37   ` Catalin Marinas
2021-12-01 19:37 ` [PATCH v2 2/4] mm: Probe for sub-page faults in fault_in_*() Catalin Marinas
2021-12-01 19:37   ` Catalin Marinas
2021-12-02  3:38   ` kernel test robot
2021-12-02  5:10   ` kernel test robot
2021-12-02  5:10     ` kernel test robot
2021-12-02 12:40   ` kernel test robot
2021-12-01 19:37 ` [PATCH v2 3/4] arm64: Add support for user sub-page fault probing Catalin Marinas
2021-12-01 19:37   ` Catalin Marinas
2021-12-01 20:29   ` Mark Rutland [this message]
2021-12-01 20:29     ` Mark Rutland
2021-12-02 16:09     ` Catalin Marinas
2021-12-02 16:09       ` Catalin Marinas
2021-12-01 19:37 ` [PATCH v2 4/4] btrfs: Avoid live-lock in search_ioctl() on hardware with sub-page faults Catalin Marinas
2021-12-01 19:37   ` Catalin Marinas
2021-12-03 15:29 ` [PATCH v2 0/4] Avoid live-lock in fault-in+uaccess loops " Andreas Gruenbacher
2021-12-03 15:29   ` Andreas Gruenbacher
2021-12-03 17:57   ` Linus Torvalds
2021-12-03 17:57     ` Linus Torvalds
2021-12-03 18:11     ` Andreas Gruenbacher
2021-12-03 18:11       ` Andreas Gruenbacher
2021-12-03 18:25       ` Linus Torvalds
2021-12-03 18:25         ` Linus Torvalds
2021-12-03 19:51   ` Catalin Marinas
2021-12-03 19:51     ` Catalin Marinas

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=YafbEpoiFB4emaPW@FVFF77S0Q05N \
    --to=mark.rutland@arm.com \
    --cc=agruenba@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=dsterba@suse.com \
    --cc=josef@toxicpanda.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will@kernel.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

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

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