From: Christian Borntraeger <borntraeger@de.ibm.com>
To: Jiri Slaby <jslaby@suse.cz>, stable@vger.kernel.org
Subject: Re: [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE
Date: Wed, 30 Mar 2016 18:33:56 +0200 [thread overview]
Message-ID: <56FBFFF4.50607@de.ibm.com> (raw)
In-Reply-To: <1459347922-14737-5-git-send-email-jslaby@suse.cz>
On 03/30/2016 04:25 PM, Jiri Slaby wrote:
> From: Christian Borntraeger <borntraeger@de.ibm.com>
>
> This patch has been added to the 3.12 stable tree. If you have any
> objections, please let us know.
>
> ===============
>
> commit 230fa253df6352af12ad0a16128760b5cb3f92df upstream.
>
> ACCESS_ONCE does not work reliably on non-scalar types. For
> example gcc 4.6 and 4.7 might remove the volatile tag for such
> accesses during the SRA (scalar replacement of aggregates) step
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145)
>
> Let's provide READ_ONCE/ASSIGN_ONCE that will do all accesses via
> scalar types as suggested by Linus Torvalds. Accesses larger than
> the machines word size cannot be guaranteed to be atomic. These
> macros will use memcpy and emit a build warning.
>
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
There have been several followup patches (e.g.
43239cbe79fc ("kernel: Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)")
7bd3e239d6c6d ("locking: Remove atomicy checks from {READ,WRITE}_ONCE")
and others.
I think this patch should not go alone.
> ---
> include/linux/compiler.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 74 insertions(+)
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 19a199414bd0..237063adbe1b 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -179,6 +179,80 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
> # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
> #endif
>
> +#include <uapi/linux/types.h>
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +#ifdef __compiletime_warning
> +__compiletime_warning("data access exceeds word size and won't be atomic")
> +#endif
> +;
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +{
> +}
> +
> +static __always_inline void __read_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
> + case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
> + case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)res, (const void *)p, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +static __always_inline void __assign_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
> + case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
> + case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)p, (const void *)res, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +/*
> + * Prevent the compiler from merging or refetching reads or writes. The
> + * compiler is also forbidden from reordering successive instances of
> + * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the
> + * compiler is aware of some particular ordering. One way to make the
> + * compiler aware of ordering is to put the two invocations of READ_ONCE,
> + * ASSIGN_ONCE or ACCESS_ONCE() in different C statements.
> + *
> + * In contrast to ACCESS_ONCE these two macros will also work on aggregate
> + * data types like structs or unions. If the size of the accessed data
> + * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
> + * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a
> + * compile-time warning.
> + *
> + * Their two major use cases are: (1) Mediating communication between
> + * process-level code and irq/NMI handlers, all running on the same CPU,
> + * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
> + * mutilate accesses that either do not require ordering or that interact
> + * with an explicit memory barrier or atomic instruction that provides the
> + * required ordering.
> + */
> +
> +#define READ_ONCE(x) \
> + ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> +#define ASSIGN_ONCE(val, x) \
> + ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> #endif /* __KERNEL__ */
>
> #endif /* __ASSEMBLY__ */
>
next prev parent reply other threads:[~2016-03-30 16:34 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-30 14:25 [patch added to 3.12-stable] ipr: Fix out-of-bounds null overwrite Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipr: Fix regression when loading firmware Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] ipv4: Don't do expensive useless work during inetdev destroy Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] umount: Do not allow unmounting rootfs Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] kernel: Provide READ_ONCE and ASSIGN_ONCE Jiri Slaby
2016-03-30 16:33 ` Christian Borntraeger [this message]
2016-03-30 14:25 ` [patch added to 3.12-stable] xen: Add RING_COPY_REQUEST() Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: don't use last request to determine minimum Tx credit Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-netback: use RING_COPY_REQUEST() throughout Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: only read request operation from shared ring once Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen-blkback: read from indirect descriptors only once Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save xen_pci_op commands before processing it Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xen/pciback: Save the number of MSI-X entries to be copied later Jiri Slaby
2016-03-30 14:25 ` [patch added to 3.12-stable] xfs: allow inode allocations in post-growfs disk space Jiri Slaby
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=56FBFFF4.50607@de.ibm.com \
--to=borntraeger@de.ibm.com \
--cc=jslaby@suse.cz \
--cc=stable@vger.kernel.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.