All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andre Przywara <andre.przywara@arm.com>
To: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: kvm@vger.kernel.org, pbonzini@redhat.com, drjones@redhat.com,
	maz@kernel.org, vladimir.murzin@arm.com, mark.rutland@arm.com,
	Laurent Vivier <lvivier@redhat.com>,
	Thomas Huth <thuth@redhat.com>,
	David Hildenbrand <david@redhat.com>
Subject: Re: [kvm-unit-tests PATCH v3 03/18] lib: Add WRITE_ONCE and READ_ONCE implementations in compiler.h
Date: Thu, 2 Jan 2020 18:03:24 +0000	[thread overview]
Message-ID: <20200102180324.085a136e@donnerap.cambridge.arm.com> (raw)
In-Reply-To: <1577808589-31892-4-git-send-email-alexandru.elisei@arm.com>

On Tue, 31 Dec 2019 16:09:34 +0000
Alexandru Elisei <alexandru.elisei@arm.com> wrote:

Hi,

> Add the WRITE_ONCE and READ_ONCE macros which are used to prevent the
> compiler from optimizing a store or a load, respectively, into something
> else.

Compared to the Linux version and found to be equivalent:

Reviewed-by: Andre Przywara <andre.przywara@arm.com>

Cheers,
Andre

> Cc: Drew Jones <drjones@redhat.com>
> Cc: Laurent Vivier <lvivier@redhat.com>
> Cc: Thomas Huth <thuth@redhat.com>
> Cc: David Hildenbrand <david@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  lib/linux/compiler.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644 lib/linux/compiler.h
> 
> diff --git a/lib/linux/compiler.h b/lib/linux/compiler.h
> new file mode 100644
> index 000000000000..2d72f18c36e5
> --- /dev/null
> +++ b/lib/linux/compiler.h
> @@ -0,0 +1,83 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Taken from Linux commit 219d54332a09 ("Linux 5.4"), from the file
> + * tools/include/linux/compiler.h, with minor changes.
> + */
> +#ifndef __LINUX_COMPILER_H
> +#define __LINUX_COMPILER_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#include <stdint.h>
> +
> +#define barrier()	asm volatile("" : : : "memory")
> +
> +#define __always_inline	inline __attribute__((always_inline))
> +
> +static __always_inline void __read_once_size(const volatile void *p, void *res, int size)
> +{
> +	switch (size) {
> +	case 1: *(uint8_t *)res = *(volatile uint8_t *)p; break;
> +	case 2: *(uint16_t *)res = *(volatile uint16_t *)p; break;
> +	case 4: *(uint32_t *)res = *(volatile uint32_t *)p; break;
> +	case 8: *(uint64_t *)res = *(volatile uint64_t *)p; break;
> +	default:
> +		barrier();
> +		__builtin_memcpy((void *)res, (const void *)p, size);
> +		barrier();
> +	}
> +}
> +
> +/*
> + * Prevent the compiler from merging or refetching reads or writes. The
> + * compiler is also forbidden from reordering successive instances of
> + * READ_ONCE and WRITE_ONCE, 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 or WRITE_ONCE in different C
> + * statements.
> + *
> + * 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 WRITE_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)					\
> +({							\
> +	union { typeof(x) __val; char __c[1]; } __u =	\
> +		{ .__c = { 0 } };			\
> +	__read_once_size(&(x), __u.__c, sizeof(x));	\
> +	__u.__val;					\
> +})
> +
> +static __always_inline void __write_once_size(volatile void *p, void *res, int size)
> +{
> +	switch (size) {
> +	case 1: *(volatile uint8_t *) p = *(uint8_t  *) res; break;
> +	case 2: *(volatile uint16_t *) p = *(uint16_t *) res; break;
> +	case 4: *(volatile uint32_t *) p = *(uint32_t *) res; break;
> +	case 8: *(volatile uint64_t *) p = *(uint64_t *) res; break;
> +	default:
> +		barrier();
> +		__builtin_memcpy((void *)p, (const void *)res, size);
> +		barrier();
> +	}
> +}
> +
> +#define WRITE_ONCE(x, val)				\
> +({							\
> +	union { typeof(x) __val; char __c[1]; } __u =	\
> +		{ .__val = (val) }; 			\
> +	__write_once_size(&(x), __u.__c, sizeof(x));	\
> +	__u.__val;					\
> +})
> +
> +#endif /* !__ASSEMBLY__ */
> +#endif /* !__LINUX_COMPILER_H */


  reply	other threads:[~2020-01-02 18:06 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-31 16:09 [kvm-unit-tests PATCH v3 00/18] arm/arm64: Various fixes Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 01/18] lib: arm/arm64: Remove unnecessary dcache maintenance operations Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 02/18] lib: arm: Add proper data synchronization barriers for TLBIs Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 03/18] lib: Add WRITE_ONCE and READ_ONCE implementations in compiler.h Alexandru Elisei
2020-01-02 18:03   ` Andre Przywara [this message]
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 04/18] lib: arm/arm64: Use WRITE_ONCE to update the translation tables Alexandru Elisei
2020-01-02 18:06   ` Andre Przywara
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 05/18] lib: arm/arm64: Remove unused CPU_OFF parameter Alexandru Elisei
2020-01-02 18:11   ` Andre Przywara
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 06/18] arm/arm64: psci: Don't run C code without stack or vectors Alexandru Elisei
2020-01-02 18:11   ` Andre Przywara
2020-01-03 15:31     ` Andrew Jones
2020-01-06 11:02       ` Alexandru Elisei
2020-01-06 13:03         ` Andrew Jones
2020-01-06 14:03           ` Alexandru Elisei
2020-01-06 10:41     ` Alexandru Elisei
2020-01-06 11:17       ` Andre Przywara
2020-01-06 11:28         ` Alexandru Elisei
2020-01-06 11:36         ` Mark Rutland
2020-01-06 11:41       ` Mark Rutland
2020-01-06 13:17         ` Andrew Jones
2020-01-06 14:12           ` Alexandru Elisei
2020-01-06 15:20             ` Andrew Jones
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 07/18] lib: arm/arm64: Add missing include for alloc_page.h in pgtable.h Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 08/18] lib: arm: Implement flush_tlb_all Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 09/18] lib: arm/arm64: Teach mmu_clear_user about block mappings Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 10/18] arm/arm64: selftest: Add prefetch abort test Alexandru Elisei
2020-01-06  9:24   ` Andrew Jones
2020-01-06 11:03     ` Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 11/18] arm64: timer: Write to ICENABLER to disable timer IRQ Alexandru Elisei
2020-01-03 13:36   ` Andre Przywara
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 12/18] arm64: timer: EOIR the interrupt after masking the timer Alexandru Elisei
2020-01-03 13:36   ` Andre Przywara
2020-01-06 11:35     ` Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 13/18] arm64: timer: Test behavior when timer disabled or masked Alexandru Elisei
2020-01-03 13:37   ` Andre Przywara
2020-01-06 13:22     ` Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 14/18] lib: arm/arm64: Refuse to disable the MMU with non-identity stack pointer Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 15/18] arm/arm64: Perform dcache clean + invalidate after turning MMU off Alexandru Elisei
2020-01-03 16:49   ` Andre Przywara
2020-01-06 14:27     ` Alexandru Elisei
2020-01-06 16:28       ` Andrew Jones
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 16/18] arm: cstart64.S: Downgrade TLBI to non-shareable in asm_mmu_enable Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 17/18] arm/arm64: Invalidate TLB before enabling MMU Alexandru Elisei
2019-12-31 16:09 ` [kvm-unit-tests PATCH v3 18/18] arm: cstart64.S: Remove icache invalidation from asm_mmu_enable Alexandru Elisei
2020-01-06  9:28 ` [kvm-unit-tests PATCH v3 00/18] arm/arm64: Various fixes Andrew Jones
2020-01-09 10:01   ` Alexandru Elisei

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=20200102180324.085a136e@donnerap.cambridge.arm.com \
    --to=andre.przywara@arm.com \
    --cc=alexandru.elisei@arm.com \
    --cc=david@redhat.com \
    --cc=drjones@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=lvivier@redhat.com \
    --cc=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=thuth@redhat.com \
    --cc=vladimir.murzin@arm.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 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.