lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 6 Jun 2019 15:54:24 +0000
From:   Jorgen Hansen <jhansen@...are.com>
To:     Peter Zijlstra <peterz@...radead.org>
CC:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Andrea Parri <andrea.parri@...rulasolutions.com>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        "will.deacon@....com" <will.deacon@....com>,
        "arnd@...db.de" <arnd@...db.de>, Vishnu DASA <vdasa@...are.com>,
        Adit Ranadive <aditr@...are.com>,
        Steven Rostedt <rostedt@...dmis.org>
Subject: Re: [PATCH] VMCI: Fixup atomic64_t abuse



> On 6 Jun 2019, at 11:34, Peter Zijlstra <peterz@...radead.org> wrote:
> 
> 
> The VMCI driver is abusing atomic64_t and atomic_t, there is no actual
> atomic RmW operations around.
> 
> Rewrite the code to use a regular u64 with READ_ONCE() and
> WRITE_ONCE() and a cast to 'unsigned long'. This fully preserves
> whatever broken there was (it's not endian-safe for starters, and also
> looks to be missing ordering).

Thanks for the cleanup.

This code is only intended for use with the vmci device driver, and that is X86 only, so during the original upstreaming no effort was made to make this work correctly on anything else.

With that in mind, it should be fine to drop the unsigned long * type casts, since the introduction of the 32 bit operations were only done to avoid an issue with cmpxchg8b on 32-bit, and just doing straight writes avoids that too.

We’ll be updating the vmci device driver to work on other architectures soonish, so will be adding barriers to enforce ordering as well at that point. If you want to leave your patch as is, we can address the type casting then.

> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
> ---
> include/linux/vmw_vmci_defs.h |   30 ++++++++++--------------------
> 1 file changed, 10 insertions(+), 20 deletions(-)
> 
> --- a/include/linux/vmw_vmci_defs.h
> +++ b/include/linux/vmw_vmci_defs.h
> @@ -438,8 +438,8 @@ enum {
> struct vmci_queue_header {
> 	/* All fields are 64bit and aligned. */
> 	struct vmci_handle handle;	/* Identifier. */
> -	atomic64_t producer_tail;	/* Offset in this queue. */
> -	atomic64_t consumer_head;	/* Offset in peer queue. */
> +	u64 producer_tail;	/* Offset in this queue. */
> +	u64 consumer_head;	/* Offset in peer queue. */
> };
> 
> /*
> @@ -740,13 +740,9 @@ static inline void *vmci_event_data_payl
>  * prefix will be used, so correctness isn't an issue, but using a
>  * 64bit operation still adds unnecessary overhead.
>  */
> -static inline u64 vmci_q_read_pointer(atomic64_t *var)
> +static inline u64 vmci_q_read_pointer(u64 *var)
> {
> -#if defined(CONFIG_X86_32)
> -	return atomic_read((atomic_t *)var);
> -#else
> -	return atomic64_read(var);
> -#endif
> +	return READ_ONCE(*(unsigned long *)var);
> }
> 
> /*
> @@ -755,23 +751,17 @@ static inline u64 vmci_q_read_pointer(at
>  * never exceeds a 32bit value in this case. On 32bit SMP, using a
>  * locked cmpxchg8b adds unnecessary overhead.
>  */
> -static inline void vmci_q_set_pointer(atomic64_t *var,
> -				      u64 new_val)
> +static inline void vmci_q_set_pointer(u64 *var, u64 new_val)
> {
> -#if defined(CONFIG_X86_32)
> -	return atomic_set((atomic_t *)var, (u32)new_val);
> -#else
> -	return atomic64_set(var, new_val);
> -#endif
> +	/* XXX buggered on big-endian */
> +	WRITE_ONCE(*(unsigned long *)var, (unsigned long)new_val);
> }
> 
> /*
>  * Helper to add a given offset to a head or tail pointer. Wraps the
>  * value of the pointer around the max size of the queue.
>  */
> -static inline void vmci_qp_add_pointer(atomic64_t *var,
> -				       size_t add,
> -				       u64 size)
> +static inline void vmci_qp_add_pointer(u64 *var, size_t add, u64 size)
> {
> 	u64 new_val = vmci_q_read_pointer(var);
> 
> @@ -848,8 +838,8 @@ static inline void vmci_q_header_init(st
> 				      const struct vmci_handle handle)
> {
> 	q_header->handle = handle;
> -	atomic64_set(&q_header->producer_tail, 0);
> -	atomic64_set(&q_header->consumer_head, 0);
> +	q_header->producer_tail = 0;
> +	q_header->consumer_head = 0;
> }
> 
> /*

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ