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]
Message-ID: <c491d47f13873f6c7fc344a34d6fd141@agner.ch>
Date:	Mon, 18 Jan 2016 09:19:52 -0800
From:	Stefan Agner <stefan@...er.ch>
To:	Mark Brown <broonie@...nel.org>
Cc:	gregkh@...uxfoundation.org, linux-kernel@...r.kernel.org
Subject: Re: [RFC] regmap: clairify max_register meaning

On 2016-01-18 08:05, Mark Brown wrote:
> On Sun, Jan 17, 2016 at 10:52:56PM -0800, Stefan Agner wrote:
> 
> Please submit one change per patch.  You've mixed a change to the
> documentation with a code here and it's really unclear what either of
> them are supposed to do.

Sure, one change per patch. I interpreted this issue as "one change"
since the interpretation of the doc lead to this implementation issue...

But I see, the issue in regcache-flat.c could be a completely
independent issue.

> 
>> Maybe I see something completely wrong here, but to me it seems
>> that the regcache-flat.c is the only code interpreting max_register
>> as register indexes rather then the maximum relative address...
> 
> I don't think I understand what the above means, sorry.  What is a
> "relative address" in the context of a register map?

My interpretation:

relative address = index * stride
absolute address = base address + relative address

For the driver at  hand I was about to set max_register to (max relative
address / 4), since that matches my interpretation of index and at first
sight seem to mach what is done in regcache-flat.c (it even works fine,
at least for 4 byte registers)....

> 
>> At least regmap.c compares with range_max, which seems to use
>> addresses.
> 
> That's a fairly large source file, can you be more specific please?
> 

e.g. in __regmap_init, just after the label skip_format_initialization.
(more on that see below)

>> -	map->cache = kcalloc(map->max_register + 1, sizeof(unsigned int),
>> -			     GFP_KERNEL);
>> +	map->cache = kzalloc(map->max_register + map->reg_stride, GFP_KERNEL);
> 
> This isn't very obvious and appears broken for a lot of devices.  It
> does two things, it converts from allocating an array of unsigned
> integers to an array of bytes and it replaces the handling of address 0
> by adding an extra element to the array with adding stride bytes on the
> end of the array.  This means that for a regmap with 16 bit values and a
> stride of 1 we'll end up allocating nowhere the space we need as we'll
> only allocate one byte per register plus an extra byte at the end but
> the implementation of the flat cache is treating the cache as an array
> of unsigned ints so needs at least four bytes per register.  It should
> wash out as the same thing if the stride is equal to the size of an
> unsigned int but most other cases will be broken.

I see, agreed, my code is certainly broken if strides <
sizeof(*reg_value).

> 
> Your changelog doesn't actually say this but I think what this is trying
> to do is make the cache more memory efficient by not allocating space
> for the registers that don't exist due to striding (ie, if we have a 4
> byte stride then currently we'll allocate space for 4 times as many
> registers as actually exist).  That's a reasonable goal but I don't
> immediately have a good idea for doing it bearing in mind that we are
> very performance sensitive here.

Yeah I saw a bug in that, but I see that this is actually just a not
very space efficient implementation detail.

> 
>> - * @max_register: Optional, specifies the maximum valid register index.
>> + * @max_register: Optional, specifies the maximum valid register address.
> 
> This is reasonable (index and address are synonyms here).

Ok, in that case I clearly interpreted index wrong.

Btw, range_min and range_max in struct regmap_range_cfg are defined as
memory addresses:
...
 * @range_min: Address of the lowest register address in virtual range. 
        
 * @range_max: Address of the highest register in virtual range.
...

Will send out a patch for the documentation change only, if you think
that this is a reasonable change too?

--
Stefan

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ