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:   Wed, 3 Nov 2021 22:53:17 +0100
From:   Ansuel Smith <ansuelsmth@...il.com>
To:     Mark Brown <broonie@...nel.org>
Cc:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH] regmap: allow to define reg_update_bits for no bus
 configuration

On Wed, Nov 03, 2021 at 09:29:11PM +0000, Mark Brown wrote:
> On Wed, Nov 03, 2021 at 08:48:37PM +0100, Ansuel Smith wrote:
> > On Wed, Nov 03, 2021 at 05:01:16PM +0000, Mark Brown wrote:
> > > On Tue, Nov 02, 2021 at 10:41:38PM +0100, Ansuel Smith wrote:
> 
> > > > -	if (regmap_volatile(map, reg) && map->reg_update_bits) {
> > > > +	if ((regmap_volatile(map, reg) || !map->bus) && map->reg_update_bits) {
> > > >  		ret = map->reg_update_bits(map->bus_context, reg, mask, val);
> > > >  		if (ret == 0 && change)
> > > >  			*change = true;
> 
> > > I don't understand this change.  The point of the check for volatile
> > > there is that if the register isn't volatile then we need to ensure that
> > > the cache gets updated with any change that happens so we need to go
> > > through paths that include cache updates.  The presence or otherwise of
> > > a bus does not seem at all relevant here.
> 
> > I put the check there to not duplicate the code. The idea here is:
> > if we are doing a regmap_update_bits operation on a no bus configuration
> > and the function have a dedicated reg_update_bits function, use that
> > instead of the normal _reg_read, check and _reg_write.
> 
> Yes, I can see that this is what the change does - the problem is that
> it's buggy.
> 
> > To workaround the CACHE problem, I can add a check and detect if cache is
> > disabled and only with that option permit to add a reg_update_bits
> > function to the map (for no bus configuration).
> 
> That's what the volatile check that is already there does - if there is
> no cache or that particular register is uncached then the register is
> volatile and we don't need to worry about updating the cache.  There is
> not and should not be any connection to how the device is physically
> accessed, any connection there is clearly an abstraction problem.
> 
> > Again the problem here is in situation where lock is handled outside of
> > the read/write and the read/modify/write operation has to be done in one
> > go so splitting this operation in 2 step (like it's done for
> > regmap_update_bits) would be problematic.
> 
> Unconditionally introducing a data corruption or power management bug
> for any device that provides an update bits operation regardless of
> their requirements to use that operation for a specific register is not
> a good idea.  If an individual device can't cope with some or all
> registers being cached then the driver for that device should configure
> it's regmap appropriately to ensure that the registers in question won't
> be cached.
> 
> > Another solution would be to expose a way to change the cache externally
> > to the regmap operation so that if someone require cache operation and
> > require also a dedicated reg_update_bits, he can do that by implementing
> > that in his own function.
> 
> I'm struggling to see a case where this would be useful without the
> register also being volatile in which case it's totally redundant.  If
> the register can change underneath us then it is by definition volatile,
> if the register can't be changed underneath us then with a cache there's
> unlikely to be any meaningful upside to using a specific read/modify/write
> operation in the first place.  You might have some case for wider
> registers where you can do a smaller transfer but that's got to be rare
> and I'd expect we'd have to be doing a lot of register I/O to care about
> the performance diffrence.
> 
> > A third solution would be check if it's possible to cache the value
> > externally to function... Something that calls the reg_update_bits
> > dedicated function and then update the cache if needed.
> 
> That's exactly what the existing volatility check does, 
> 
> > But do we really need to add all this complexity when we can just deny
> > an option with cache enabled and force to use the normal way (else part
> > in this function)
> 
> > Hope I was able to explain better why we need this change.
> 
> We do not need this change.  The change that is being proposed will
> cause bugs, my best guess is that it's trying to work around a bug in
> the driver you're developing where it's enabling caching but not marking
> all the volatile registers properly.  If there is any change needed in
> the _update_bits() implementation then where we get a device specific
> _update_bits() operation from should have no influence on our decision
> to use it, doing that is a clear sign that there's an abstraction
> problem.

I think I'm missing something. The user case is a driver that
have CACHE DISABLED. The !map->bus check is added just to limit this to
a no bus configuration not to permit this with CACHE enabled. The limit
I was referring was in the init function where the update_bits is
assigned to the map. I honestly didn't notice that anything with cache
disabled was flagged as volatile.

So the rest of the changes permit to declare a update_bits function
for a no bus configuration is good?

Again that was the main reason of this patch. Obviously I didn't want to
introduce bugs or an hack to bypass the cache thing. Just I notice this
was permitted with a bus configuration but the no bus configuration
lacks any way to configure a update_bits function.

-- 
	Ansuel

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ