Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964913AbcKKXH7 (ORCPT ); Fri, 11 Nov 2016 18:07:59 -0500 Received: from bombadil.infradead.org ([198.137.202.9]:33207 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935328AbcKKXH6 (ORCPT ); Fri, 11 Nov 2016 18:07:58 -0500 Date: Sat, 12 Nov 2016 00:07:50 +0100 From: Peter Zijlstra To: Mark Rutland Cc: kernel-hardening@lists.openwall.com, Kees Cook , Greg KH , Will Deacon , Elena Reshetova , Arnd Bergmann , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , LKML Subject: Re: [kernel-hardening] Re: [RFC v4 PATCH 00/13] HARDENED_ATOMIC Message-ID: <20161111230750.GP3157@twins.programming.kicks-ass.net> References: <20161110203749.GV3117@twins.programming.kicks-ass.net> <20161110204838.GE17134@arm.com> <20161110211310.GX3117@twins.programming.kicks-ass.net> <20161110222744.GD8086@kroah.com> <20161110235714.GR3568@worktop.programming.kicks-ass.net> <1478824161.7326.5.camel@cvidal.org> <20161111124126.GG11945@leverpostej> <20161111124755.GI3117@twins.programming.kicks-ass.net> <20161111130034.GO3157@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20161111130034.GO3157@twins.programming.kicks-ass.net> User-Agent: Mutt/1.5.23.1 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 660 Lines: 29 On Fri, Nov 11, 2016 at 02:00:34PM +0100, Peter Zijlstra wrote: > +static inline bool refcount_sub_and_test(int i, refcount_t *r) > +{ > + unsigned int old, new, val = atomic_read(&r->refs); > + > + for (;;) { regardless of the sub_and_test vs inc_and_test issue, this should probably also have: if (val == UINT_MAX) return false; such that we stay saturated. If for some reason someone can trigger more dec's than inc's, we'd be hosed. > + new = val - i; > + if (new > val) > + BUG(); /* underflow */ > + > + old = atomic_cmpxchg_release(&r->refs, val, new); > + if (old == val) > + break; > + > + val = old; > + } > + > + return !new; > +}