Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support
From: Dmitry Torokhov @ 2018-03-16  0:06 UTC (permalink / raw)
  To: Nick Dyer; +Cc: linux-input, Benson Leung, Olof Johansson, linux-kernel
In-Reply-To: <20180314205938.GD26353@lava.h.shmanahar.org>

On Wed, Mar 14, 2018 at 08:59:38PM +0000, Nick Dyer wrote:
> On Mon, Mar 12, 2018 at 12:09:07PM -0700, Dmitry Torokhov wrote:
> > Date: Mon, 12 Mar 2018 12:09:07 -0700
> > From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > To: linux-input@vger.kernel.org, Benson Leung <bleung@chromium.org>
> > Cc: Nick Dyer <nick@shmanahar.org>, Olof Johansson <olof@lixom.net>,
> >  linux-kernel@vger.kernel.org
> > Subject: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support
> > 
> > Now that there are no users of custom Atmel platform data, and everyone
> > has switched to the generic device properties, we can remove support for
> > the platform data.
> 
> Thanks, this is a nice tidy up.
> 
> > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> > ---
> >  MAINTAINERS                                |   1 -
> >  drivers/input/touchscreen/atmel_mxt_ts.c   | 125 +++++++++------------
> >  include/linux/platform_data/atmel_mxt_ts.h |  31 -----
> >  3 files changed, 50 insertions(+), 107 deletions(-)
> >  delete mode 100644 include/linux/platform_data/atmel_mxt_ts.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 4623caf8d72d8..37b70874a4771 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2394,7 +2394,6 @@ T:	git git://github.com/ndyer/linux.git
> >  S:	Maintained
> >  F:	Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> >  F:	drivers/input/touchscreen/atmel_mxt_ts.c
> > -F:	include/linux/platform_data/atmel_mxt_ts.h
> >  
> >  ATMEL SAMA5D2 ADC DRIVER
> >  M:	Ludovic Desroches <ludovic.desroches@microchip.com>
> > diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> > index cf2aac4e79ae8..642211254acc4 100644
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -23,10 +23,10 @@
> >  #include <linux/delay.h>
> >  #include <linux/firmware.h>
> >  #include <linux/i2c.h>
> > -#include <linux/platform_data/atmel_mxt_ts.h>
> >  #include <linux/input/mt.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/of.h>
> > +#include <linux/property.h>
> >  #include <linux/slab.h>
> >  #include <linux/gpio/consumer.h>
> >  #include <linux/property.h>
> > @@ -274,7 +274,6 @@ struct mxt_data {
> >  	struct i2c_client *client;
> >  	struct input_dev *input_dev;
> >  	char phys[64];		/* device physical location */
> > -	const struct mxt_platform_data *pdata;
> >  	struct mxt_object *object_table;
> >  	struct mxt_info info;
> >  	unsigned int irq;
> > @@ -325,6 +324,9 @@ struct mxt_data {
> >  
> >  	/* for config update handling */
> >  	struct completion crc_completion;
> > +
> > +	u32 *t19_keymap;
> > +	unsigned int t19_num_keys;
> >  };
> >  
> >  struct mxt_vb2_buffer {
> > @@ -743,15 +745,14 @@ static int mxt_write_object(struct mxt_data *data,
> >  static void mxt_input_button(struct mxt_data *data, u8 *message)
> >  {
> >  	struct input_dev *input = data->input_dev;
> > -	const struct mxt_platform_data *pdata = data->pdata;
> >  	int i;
> >  
> > -	for (i = 0; i < pdata->t19_num_keys; i++) {
> > -		if (pdata->t19_keymap[i] == KEY_RESERVED)
> > +	for (i = 0; i < data->t19_num_keys; i++) {
> > +		if (data->t19_keymap[i] == KEY_RESERVED)
> >  			continue;
> >  
> >  		/* Active-low switch */
> > -		input_report_key(input, pdata->t19_keymap[i],
> > +		input_report_key(input, data->t19_keymap[i],
> >  				 !(message[1] & BIT(i)));
> >  	}
> >  }
> > @@ -759,7 +760,7 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)
> >  static void mxt_input_sync(struct mxt_data *data)
> >  {
> >  	input_mt_report_pointer_emulation(data->input_dev,
> > -					  data->pdata->t19_num_keys);
> > +					  data->t19_num_keys);
> >  	input_sync(data->input_dev);
> >  }
> >  
> > @@ -1859,7 +1860,6 @@ static void mxt_input_close(struct input_dev *dev);
> >  static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
> >  				   struct mxt_data *data)
> >  {
> > -	const struct mxt_platform_data *pdata = data->pdata;
> >  	int i;
> >  
> >  	input_dev->name = "Atmel maXTouch Touchpad";
> > @@ -1873,15 +1873,14 @@ static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
> >  	input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
> >  			  MXT_PIXELS_PER_MM);
> >  
> > -	for (i = 0; i < pdata->t19_num_keys; i++)
> > -		if (pdata->t19_keymap[i] != KEY_RESERVED)
> > +	for (i = 0; i < data->t19_num_keys; i++)
> > +		if (data->t19_keymap[i] != KEY_RESERVED)
> >  			input_set_capability(input_dev, EV_KEY,
> > -					     pdata->t19_keymap[i]);
> > +					     data->t19_keymap[i]);
> >  }
> >  
> >  static int mxt_initialize_input_device(struct mxt_data *data)
> >  {
> > -	const struct mxt_platform_data *pdata = data->pdata;
> >  	struct device *dev = &data->client->dev;
> >  	struct input_dev *input_dev;
> >  	int error;
> > @@ -1947,7 +1946,7 @@ static int mxt_initialize_input_device(struct mxt_data *data)
> >  	}
> >  
> >  	/* If device has buttons we assume it is a touchpad */
> > -	if (pdata->t19_num_keys) {
> > +	if (data->t19_num_keys) {
> >  		mxt_set_up_as_touchpad(input_dev, data);
> >  		mt_flags |= INPUT_MT_POINTER;
> >  	} else {
> > @@ -2921,51 +2920,42 @@ static void mxt_input_close(struct input_dev *dev)
> >  	mxt_stop(data);
> >  }
> >  
> > -static const struct mxt_platform_data *
> > -mxt_parse_device_properties(struct i2c_client *client)
> > +static int mxt_parse_device_properties(struct mxt_data *data)
> >  {
> >  	static const char keymap_property[] = "linux,gpio-keymap";
> > -	struct mxt_platform_data *pdata;
> > +	struct device *dev = &data->client->dev;
> >  	u32 *keymap;
> >  	int n_keys;
> >  	int error;
> >  
> > -	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
> > -	if (!pdata)
> > -		return ERR_PTR(-ENOMEM);
> > -
> > -	if (device_property_present(&client->dev, keymap_property)) {
> > -		n_keys = device_property_read_u32_array(&client->dev,
> > -							keymap_property,
> > +	if (device_property_present(dev, keymap_property)) {
> > +		n_keys = device_property_read_u32_array(dev, keymap_property,
> >  							NULL, 0);
> >  		if (n_keys <= 0) {
> >  			error = n_keys < 0 ? n_keys : -EINVAL;
> > -			dev_err(&client->dev,
> > -				"invalid/malformed '%s' property: %d\n",
> > +			dev_err(dev, "invalid/malformed '%s' property: %d\n",
> >  				keymap_property, error);
> > -			return ERR_PTR(error);
> > +			return error;
> >  		}
> >  
> > -		keymap = devm_kmalloc_array(&client->dev, n_keys, sizeof(u32),
> > +		keymap = devm_kmalloc_array(dev, n_keys, sizeof(*keymap),
> >  					    GFP_KERNEL);
> >  		if (!keymap)
> > -			return ERR_PTR(-ENOMEM);
> > +			return -ENOMEM;
> >  
> > -		error = device_property_read_u32_array(&client->dev,
> > -						       keymap_property,
> > +		error = device_property_read_u32_array(dev, keymap_property,
> >  						       keymap, n_keys);
> >  		if (error) {
> > -			dev_err(&client->dev,
> > -				"failed to parse '%s' property: %d\n",
> > +			dev_err(dev, "failed to parse '%s' property: %d\n",
> >  				keymap_property, error);
> > -			return ERR_PTR(error);
> > +			return error;
> >  		}
> >  
> > -		pdata->t19_keymap = keymap;
> > -		pdata->t19_num_keys = n_keys;
> > +		data->t19_keymap = keymap;
> > +		data->t19_num_keys = n_keys;
> >  	}
> >  
> > -	return pdata;
> > +	return 0;
> >  }
> >  
> >  #ifdef CONFIG_ACPI
> > @@ -3048,25 +3038,12 @@ static const struct dmi_system_id mxt_dmi_table[] = {
> >  	{ }
> >  };
> >  
> > -static int mxt_acpi_probe(struct i2c_client *client)
> > +static int mxt_prepare_acpi_properties(struct i2c_client *client)
> >  {
> >  	struct acpi_device *adev;
> >  	const struct dmi_system_id *system_id;
> >  	const struct mxt_acpi_platform_data *acpi_pdata;
> >  
> > -	/*
> > -	 * Ignore ACPI devices representing bootloader mode.
> > -	 *
> > -	 * This is a bit of a hack: Google Chromebook BIOS creates ACPI
> > -	 * devices for both application and bootloader modes, but we are
> > -	 * interested in application mode only (if device is in bootloader
> > -	 * mode we'll end up switching into application anyway). So far
> > -	 * application mode addresses were all above 0x40, so we'll use it
> > -	 * as a threshold.
> > -	 */
> > -	if (client->addr < 0x40)
> > -		return -ENXIO;
> 
> Could you use 0x4a, since that's the lowest application mode address,
> same in the other place.

OK, this is existing code though, so I'll make a separate patch.

> 
> Can I ask if you've checked the behaviour if the device is probed while
> it's already in bootloader mode? Ideally you want to be able to recover
> from a bad firmware flash.

Yes, the device will come up at the bootloader address, but we will
ignore it here. The 2nd ACPI device with application mode address will
be probed, and we'll fail to read anything in mxt_initialize() and will
try to see if it responds at the bootloader address. It did work for me.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data
From: Dmitry Torokhov @ 2018-03-15 23:56 UTC (permalink / raw)
  To: Nick Dyer; +Cc: linux-input, Benson Leung, Olof Johansson, linux-kernel
In-Reply-To: <20180314205123.GA26353@lava.h.shmanahar.org>

On Wed, Mar 14, 2018 at 08:51:24PM +0000, Nick Dyer wrote:
> Hi Dmitry-
> 
> Thanks for sending these patches!
> 
> On Mon, Mar 12, 2018 at 12:08:54PM -0700, Dmitry Torokhov wrote:
> > The way we are supposed to put controller to sleep and wake it up does not
> > depend on the platform, but rather on controller itself. Controllers using
> > T9 require manipulating T9 control register, while others, using newer
> > T100, should be put to sleep by adjusting T7 power config.
> 
> I'm afraid this is actually a misconception. If you look at object table
> for the older T9 device, you'll find it has the T7 object and it in fact
> works exactly the same way as the T100-based device.
> 
> The MXT_SUSPEND_T9_CTRL is in there because on your older Pixel devices
> the config saved into NVRAM on the touch controller has a zero byte in
> the T9 CTRL setting, meaning the touch controller will never wake up
> unless the driver knows to write 0x83 into it.

Ah, OK, I see. I would really like to drop this pdata->suspend_mode
stuff and I do not want to create "pixel-screwed-up" property either...
I guess for the time being I'll put a DMI quirk for Link to restore T9
control method, and then look into cleaning it all up. We have quite a
bit different code in chromeos kernel trees and I'd like to reconcile
it.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 23:49 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CA+55aFyRV9KXzeQZpVYsZYVUJm-ASgu_4_1+8Y8-0KH-YT2M8Q@mail.gmail.com>

On Thu, Mar 15, 2018 at 4:46 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> What I'm *not* so much ok with is "const_max(5,sizeof(x))" erroring
> out, or silently causing insane behavior due to hidden subtle type
> casts..

Yup! I like it as an explicit argument. Thanks!

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Linus Torvalds @ 2018-03-15 23:47 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CA+55aFyRV9KXzeQZpVYsZYVUJm-ASgu_4_1+8Y8-0KH-YT2M8Q@mail.gmail.com>

On Thu, Mar 15, 2018 at 4:46 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> Well, the explicit typing allows that mixing, in that you can just
> have "const_max_t(5,sizeof(x))"

I obviously meant "const_max_t(size_t,5,sizeof(x))". Heh.

                Linus

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Linus Torvalds @ 2018-03-15 23:46 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CAGXu5jLHW00UmSDyAmdLpin6L636XbP3brH=pn4qh1bN87AirA@mail.gmail.com>

On Thu, Mar 15, 2018 at 4:41 PM, Kees Cook <keescook@chromium.org> wrote:
>
> I much prefer explicit typing, but both you and Rasmus mentioned
> wanting the int/sizeof_t mixing.

Well, the explicit typing allows that mixing, in that you can just
have "const_max_t(5,sizeof(x))"

So I'm ok with that.

What I'm *not* so much ok with is "const_max(5,sizeof(x))" erroring
out, or silently causing insane behavior due to hidden subtle type
casts..

                Linus

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 23:41 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CA+55aFzO12QMFJHe8osoWfph8jnjgp_jLUQWmgbNmth_KwPxXw@mail.gmail.com>

On Thu, Mar 15, 2018 at 4:34 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Thu, Mar 15, 2018 at 3:46 PM, Kees Cook <keescook@chromium.org> wrote:
>>
>> So, AIUI, I can either get strict type checking, in which case, this
>> is rejected (which I assume there is still a desire to have):
>>
>> int foo[const_max(6, sizeof(whatever))];
>
> Ehh, yes, that looks fairly sane, and erroring out would be annoying.
>
> But maybe we should just make the type explicit, and make it "const_max_t()"?
>
> I think all the existing users are of type "max_t()" anyway due to the
> very same issue, no?

All but one are using max()[1]. One case uses max_t() to get u32.

> At least if there's an explicit type like 'size_t', then passing in
> "-1" becoming a large unsigned integer is understandable and clear,
> not just some odd silent behavior.
>
> Put another way: I think it's unacceptable that
>
>      const_max(-1,6)
>
> magically becomes a huge positive number like in that patch of yours, but
>
>      const_max_t(size_t, -1, 6)
>
> *obviously* is a huge positive number.
>
> The two things would *do* the same thing, but in the second case the
> type is explicit and visible.
>
>> due to __builtin_types_compatible_p() rejecting it, or I can construct
>> a "positive arguments only" test, in which the above is accepted, but
>> this is rejected:
>
> That sounds acceptable too, although the "const_max_t()" thing is
> presumably going to be simpler?

I much prefer explicit typing, but both you and Rasmus mentioned
wanting the int/sizeof_t mixing. I'm totally happy with const_max_t()
-- even if it makes my line-wrapping harder due to the longer name. ;)

I'll resend in a moment...

-Kees

[1] https://patchwork.kernel.org/patch/10285709/

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Linus Torvalds @ 2018-03-15 23:34 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CAGXu5jLHam5kz18k9uvhsz2WYodkF2v1tsEOV4Sx0O7jir4B3A@mail.gmail.com>

On Thu, Mar 15, 2018 at 3:46 PM, Kees Cook <keescook@chromium.org> wrote:
>
> So, AIUI, I can either get strict type checking, in which case, this
> is rejected (which I assume there is still a desire to have):
>
> int foo[const_max(6, sizeof(whatever))];

Ehh, yes, that looks fairly sane, and erroring out would be annoying.

But maybe we should just make the type explicit, and make it "const_max_t()"?

I think all the existing users are of type "max_t()" anyway due to the
very same issue, no?

At least if there's an explicit type like 'size_t', then passing in
"-1" becoming a large unsigned integer is understandable and clear,
not just some odd silent behavior.

Put another way: I think it's unacceptable that

     const_max(-1,6)

magically becomes a huge positive number like in that patch of yours, but

     const_max_t(size_t, -1, 6)

*obviously* is a huge positive number.

The two things would *do* the same thing, but in the second case the
type is explicit and visible.

> due to __builtin_types_compatible_p() rejecting it, or I can construct
> a "positive arguments only" test, in which the above is accepted, but
> this is rejected:

That sounds acceptable too, although the "const_max_t()" thing is
presumably going to be simpler?

                 Linus

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 23:31 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Linus Torvalds, Andrew Morton, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CANiq72m7GEZS=Wkzg5KLkTnzW8vYz8X90OwVs4r5vcCCAp1-Pg@mail.gmail.com>

On Thu, Mar 15, 2018 at 4:17 PM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>> The full one, using your naming convention:
>>
>> #define const_max(x, y)                                          \
>>     ({                                                           \
>>         if (!__builtin_constant_p(x))                            \
>>             __error_not_const_arg();                             \
>>         if (!__builtin_constant_p(y))                            \
>>             __error_not_const_arg();                             \
>>         if (!__builtin_types_compatible_p(typeof(x), typeof(y))) \
>>             __error_incompatible_types();                        \
>>         if ((x) < 0)                                             \
>>             __error_not_positive_arg();                          \
>>         if ((y) < 0)                                             \
>>             __error_not_positive_arg();                          \
>>         __builtin_choose_expr((x) > (y), (x), (y));              \
>>     })
>>
>
> Nevermind... gcc doesn't take that as a constant expr, even if it
> compiles as one at -O0.

Yeah, unfortunately. :(

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Miguel Ojeda @ 2018-03-15 23:17 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linus Torvalds, Andrew Morton, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CANiq72nEsno3JH=c_Xaf9gn1pJdM=ni6Z0ZUDqcEF07FT+SBSw@mail.gmail.com>

On Fri, Mar 16, 2018 at 12:08 AM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
> On Thu, Mar 15, 2018 at 11:58 PM, Miguel Ojeda
> <miguel.ojeda.sandonis@gmail.com> wrote:
>> On Thu, Mar 15, 2018 at 11:46 PM, Kees Cook <keescook@chromium.org> wrote:
>>>
>>> By using this eye-bleed:
>>>
>>> size_t __error_not_const_arg(void) \
>>> __compiletime_error("const_max() used with non-compile-time constant arg");
>>> size_t __error_not_positive_arg(void) \
>>> __compiletime_error("const_max() used with negative arg");
>>> #define const_max(x, y)                                                 \
>>>         __builtin_choose_expr(__builtin_constant_p(x) &&                \
>>>                               __builtin_constant_p(y),                  \
>>>                 __builtin_choose_expr((x) >= 0 && (y) >= 0,             \
>>>                                       (typeof(x))(x) > (typeof(y))(y) ? \
>>>                                         (x) : (y),                      \
>>>                                       __error_not_positive_arg()),      \
>>>                 __error_not_const_arg())
>>>
>>
>> I was writing it like this:
>>
>> #define const_max(a, b) \
>>     ({ \
>>         if ((a) < 0) \
>>             __const_max_called_with_negative_value(); \
>>         if ((b) < 0) \
>>             __const_max_called_with_negative_value(); \
>>         if (!__builtin_types_compatible_p(typeof(a), typeof(b))) \
>>             __const_max_called_with_incompatible_types(); \
>>         __builtin_choose_expr((a) > (b), (a), (b)); \
>> })
>
> The full one, using your naming convention:
>
> #define const_max(x, y)                                          \
>     ({                                                           \
>         if (!__builtin_constant_p(x))                            \
>             __error_not_const_arg();                             \
>         if (!__builtin_constant_p(y))                            \
>             __error_not_const_arg();                             \
>         if (!__builtin_types_compatible_p(typeof(x), typeof(y))) \
>             __error_incompatible_types();                        \
>         if ((x) < 0)                                             \
>             __error_not_positive_arg();                          \
>         if ((y) < 0)                                             \
>             __error_not_positive_arg();                          \
>         __builtin_choose_expr((x) > (y), (x), (y));              \
>     })
>

Nevermind... gcc doesn't take that as a constant expr, even if it
compiles as one at -O0.

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Miguel Ojeda @ 2018-03-15 23:08 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linus Torvalds, Andrew Morton, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CANiq72k4qvXBy-VbFc5uOh-wAMx0yui5JokzX=NXtgZJ6F_NEg@mail.gmail.com>

On Thu, Mar 15, 2018 at 11:58 PM, Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
> On Thu, Mar 15, 2018 at 11:46 PM, Kees Cook <keescook@chromium.org> wrote:
>>
>> By using this eye-bleed:
>>
>> size_t __error_not_const_arg(void) \
>> __compiletime_error("const_max() used with non-compile-time constant arg");
>> size_t __error_not_positive_arg(void) \
>> __compiletime_error("const_max() used with negative arg");
>> #define const_max(x, y)                                                 \
>>         __builtin_choose_expr(__builtin_constant_p(x) &&                \
>>                               __builtin_constant_p(y),                  \
>>                 __builtin_choose_expr((x) >= 0 && (y) >= 0,             \
>>                                       (typeof(x))(x) > (typeof(y))(y) ? \
>>                                         (x) : (y),                      \
>>                                       __error_not_positive_arg()),      \
>>                 __error_not_const_arg())
>>
>
> I was writing it like this:
>
> #define const_max(a, b) \
>     ({ \
>         if ((a) < 0) \
>             __const_max_called_with_negative_value(); \
>         if ((b) < 0) \
>             __const_max_called_with_negative_value(); \
>         if (!__builtin_types_compatible_p(typeof(a), typeof(b))) \
>             __const_max_called_with_incompatible_types(); \
>         __builtin_choose_expr((a) > (b), (a), (b)); \
> })

The full one, using your naming convention:

#define const_max(x, y)                                          \
    ({                                                           \
        if (!__builtin_constant_p(x))                            \
            __error_not_const_arg();                             \
        if (!__builtin_constant_p(y))                            \
            __error_not_const_arg();                             \
        if (!__builtin_types_compatible_p(typeof(x), typeof(y))) \
            __error_incompatible_types();                        \
        if ((x) < 0)                                             \
            __error_not_positive_arg();                          \
        if ((y) < 0)                                             \
            __error_not_positive_arg();                          \
        __builtin_choose_expr((x) > (y), (x), (y));              \
    })

Miguel

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Miguel Ojeda @ 2018-03-15 22:58 UTC (permalink / raw)
  To: Kees Cook
  Cc: Linus Torvalds, Andrew Morton, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CAGXu5jLHam5kz18k9uvhsz2WYodkF2v1tsEOV4Sx0O7jir4B3A@mail.gmail.com>

On Thu, Mar 15, 2018 at 11:46 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Mar 15, 2018 at 3:23 PM, Linus Torvalds
> <torvalds@linux-foundation.org> wrote:
>> On Thu, Mar 15, 2018 at 3:16 PM, Kees Cook <keescook@chromium.org> wrote:
>>>
>>> size_t __error_not_const_arg(void) \
>>> __compiletime_error("const_max() used with non-compile-time constant arg");
>>> #define const_max(x, y)                                         \
>>>         __builtin_choose_expr(__builtin_constant_p(x) &&        \
>>>                               __builtin_constant_p(y),          \
>>>                               (typeof(x))(x) > (typeof(y))(y) ? \
>>>                                         (x) : (y),              \
>>>                               __error_not_const_arg())
>>>
>>> Is typeof() forcing enums to int? Regardless, I'll put this through
>>> larger testing. How does that look?
>>
>> Ok, that alleviates my worry about one class of insane behavior, but
>> it does raise a few other questions:
>>
>>  - what drugs is gcc on where (typeof(x)(x)) makes a difference? Funky.
>
> Yeah, that's why I didn't even try that originally. But in looking
> back at max() again, it seemed to be the only thing missing that would
> handle the enum evaluation, which turned out to be true.
>
>>  - this does have the usual "what happen if you do
>>
>>      const_max(-1,sizeof(x))
>>
>> where the comparison will now be done in 'size_t', and -1 ends up
>> being a very very big unsigned integer.
>>
>> Is there no way to get that type checking inserted? Maybe now is a
>> good point for that __builtin_types_compatible(), and add it to the
>> constness checking (and change the name of that error case function)?
>
> So, AIUI, I can either get strict type checking, in which case, this
> is rejected (which I assume there is still a desire to have):
>
> int foo[const_max(6, sizeof(whatever))];

Is it that bad to just call it with (size_t)6?

>
> due to __builtin_types_compatible_p() rejecting it, or I can construct
> a "positive arguments only" test, in which the above is accepted, but
> this is rejected:
>
> int foo[const_max(-1, sizeof(whatever))];

Do we need this case?

>
> By using this eye-bleed:
>
> size_t __error_not_const_arg(void) \
> __compiletime_error("const_max() used with non-compile-time constant arg");
> size_t __error_not_positive_arg(void) \
> __compiletime_error("const_max() used with negative arg");
> #define const_max(x, y)                                                 \
>         __builtin_choose_expr(__builtin_constant_p(x) &&                \
>                               __builtin_constant_p(y),                  \
>                 __builtin_choose_expr((x) >= 0 && (y) >= 0,             \
>                                       (typeof(x))(x) > (typeof(y))(y) ? \
>                                         (x) : (y),                      \
>                                       __error_not_positive_arg()),      \
>                 __error_not_const_arg())
>

I was writing it like this:

#define const_max(a, b) \
    ({ \
        if ((a) < 0) \
            __const_max_called_with_negative_value(); \
        if ((b) < 0) \
            __const_max_called_with_negative_value(); \
        if (!__builtin_types_compatible_p(typeof(a), typeof(b))) \
            __const_max_called_with_incompatible_types(); \
        __builtin_choose_expr((a) > (b), (a), (b)); \
})

Cheers,
Miguel


> -Kees
>
> --
> Kees Cook
> Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 22:46 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CA+55aFwDJ906oQ-98L2DNrjfKtb6cd5ykwMxpG942qxCFmAoEQ@mail.gmail.com>

On Thu, Mar 15, 2018 at 3:23 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Thu, Mar 15, 2018 at 3:16 PM, Kees Cook <keescook@chromium.org> wrote:
>>
>> size_t __error_not_const_arg(void) \
>> __compiletime_error("const_max() used with non-compile-time constant arg");
>> #define const_max(x, y)                                         \
>>         __builtin_choose_expr(__builtin_constant_p(x) &&        \
>>                               __builtin_constant_p(y),          \
>>                               (typeof(x))(x) > (typeof(y))(y) ? \
>>                                         (x) : (y),              \
>>                               __error_not_const_arg())
>>
>> Is typeof() forcing enums to int? Regardless, I'll put this through
>> larger testing. How does that look?
>
> Ok, that alleviates my worry about one class of insane behavior, but
> it does raise a few other questions:
>
>  - what drugs is gcc on where (typeof(x)(x)) makes a difference? Funky.

Yeah, that's why I didn't even try that originally. But in looking
back at max() again, it seemed to be the only thing missing that would
handle the enum evaluation, which turned out to be true.

>  - this does have the usual "what happen if you do
>
>      const_max(-1,sizeof(x))
>
> where the comparison will now be done in 'size_t', and -1 ends up
> being a very very big unsigned integer.
>
> Is there no way to get that type checking inserted? Maybe now is a
> good point for that __builtin_types_compatible(), and add it to the
> constness checking (and change the name of that error case function)?

So, AIUI, I can either get strict type checking, in which case, this
is rejected (which I assume there is still a desire to have):

int foo[const_max(6, sizeof(whatever))];

due to __builtin_types_compatible_p() rejecting it, or I can construct
a "positive arguments only" test, in which the above is accepted, but
this is rejected:

int foo[const_max(-1, sizeof(whatever))];

By using this eye-bleed:

size_t __error_not_const_arg(void) \
__compiletime_error("const_max() used with non-compile-time constant arg");
size_t __error_not_positive_arg(void) \
__compiletime_error("const_max() used with negative arg");
#define const_max(x, y)                                                 \
        __builtin_choose_expr(__builtin_constant_p(x) &&                \
                              __builtin_constant_p(y),                  \
                __builtin_choose_expr((x) >= 0 && (y) >= 0,             \
                                      (typeof(x))(x) > (typeof(y))(y) ? \
                                        (x) : (y),                      \
                                      __error_not_positive_arg()),      \
                __error_not_const_arg())

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Linus Torvalds @ 2018-03-15 22:23 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CAGXu5jKtv=a8qTy1-AfbzNRB=Azb8V7Pt1M4QMVYNKg6+Ci7=Q@mail.gmail.com>

On Thu, Mar 15, 2018 at 3:16 PM, Kees Cook <keescook@chromium.org> wrote:
>
> size_t __error_not_const_arg(void) \
> __compiletime_error("const_max() used with non-compile-time constant arg");
> #define const_max(x, y)                                         \
>         __builtin_choose_expr(__builtin_constant_p(x) &&        \
>                               __builtin_constant_p(y),          \
>                               (typeof(x))(x) > (typeof(y))(y) ? \
>                                         (x) : (y),              \
>                               __error_not_const_arg())
>
> Is typeof() forcing enums to int? Regardless, I'll put this through
> larger testing. How does that look?

Ok, that alleviates my worry about one class of insane behavior, but
it does raise a few other questions:

 - what drugs is gcc on where (typeof(x)(x)) makes a difference? Funky.

 - this does have the usual "what happen if you do

     const_max(-1,sizeof(x))

where the comparison will now be done in 'size_t', and -1 ends up
being a very very big unsigned integer.

Is there no way to get that type checking inserted? Maybe now is a
good point for that __builtin_types_compatible(), and add it to the
constness checking (and change the name of that error case function)?

          Linus

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 22:16 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <CA+55aFzu+VU_FVZdbLCZttUspZdJCvBhkuo4V69H=XnqmLrpLA@mail.gmail.com>

On Thu, Mar 15, 2018 at 2:42 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Thu, Mar 15, 2018 at 12:47 PM, Kees Cook <keescook@chromium.org> wrote:
>>
>> To gain the ability to compare differing types, the arguments are
>> explicitly cast to size_t.
>
> Ugh, I really hate this.
>
> It silently does insane things if you do
>
>    const_max(-1,6)
>
> and there is nothing in the name that implies that you can't use
> negative constants.

Yeah, I didn't like that effect either. I was seeing this:

./include/linux/kernel.h:836:14: warning: comparison between ‘enum
<anonymous>’ and ‘enum <anonymous>’ [-Wenum-compare]
          (x) > (y) ? \
              ^
./include/linux/kernel.h:838:7: note: in definition of macro ‘const_max’
      (y),  \
       ^
net/ipv6/proc.c:34:11: note: in expansion of macro ‘const_max’
           const_max(IPSTATS_MIB_MAX, ICMP_MIB_MAX))
           ^~~~~~~~~

But it turns out that just doing a typeof() fixes this, and there's no
need for the hard cast to size_t:

size_t __error_not_const_arg(void) \
__compiletime_error("const_max() used with non-compile-time constant arg");
#define const_max(x, y)                                         \
        __builtin_choose_expr(__builtin_constant_p(x) &&        \
                              __builtin_constant_p(y),          \
                              (typeof(x))(x) > (typeof(y))(y) ? \
                                        (x) : (y),              \
                              __error_not_const_arg())

Is typeof() forcing enums to int? Regardless, I'll put this through
larger testing. How does that look?

-Kees

-- 
Kees Cook
Pixel Security

^ permalink raw reply

* Re: [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Linus Torvalds @ 2018-03-15 21:42 UTC (permalink / raw)
  To: Kees Cook
  Cc: Andrew Morton, Josh Poimboeuf, Rasmus Villemoes, Randy Dunlap,
	Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott, linux-input,
	linux-btrfs, Network Development, Linux Kernel Mailing List,
	Kernel Hardening
In-Reply-To: <1521143266-31350-2-git-send-email-keescook@chromium.org>

On Thu, Mar 15, 2018 at 12:47 PM, Kees Cook <keescook@chromium.org> wrote:
>
> To gain the ability to compare differing types, the arguments are
> explicitly cast to size_t.

Ugh, I really hate this.

It silently does insane things if you do

   const_max(-1,6)

and there is nothing in the name that implies that you can't use
negative constants.

                   Linus

^ permalink raw reply

* Re: [PATCH v5 0/4] new driver for Valve Steam Controller
From: Rodrigo Rivas Costa @ 2018-03-15 21:06 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Clément VUCHENER, Jiri Kosina, Pierre-Loup A. Griffais,
	Cameron Gutman, lkml, linux-input
In-Reply-To: <CAO-hwJJqDM5Y7t-hpZ_s7EzjVki00ME7fd_7iUWcgaTZ9o906g@mail.gmail.com>

On Wed, Mar 14, 2018 at 05:39:25PM +0100, Benjamin Tissoires wrote:
> On Mon, Mar 12, 2018 at 9:51 PM, Rodrigo Rivas Costa
> <rodrigorivascosta@gmail.com> wrote:
> > On Mon, Mar 12, 2018 at 03:30:43PM +0100, Clément VUCHENER wrote:
> >> 2018-03-11 20:58 GMT+01:00 Rodrigo Rivas Costa <rodrigorivascosta@gmail.com>:
> >> > This patchset implements a driver for Valve Steam Controller, based on a
> >> > reverse analysis by myself.
> >> >
> >> > Sorry, I've been out of town for a few weeks and couldn't keep up with this...
> >> >
> >> > @Pierre-Loup and @Clément, could you please have another look at this and
> >> > check if it is worthy? Benjamin will not commit it without an express ACK from
> >> > Valve. Of course he is right to be cautious, but I checked this driver with
> >> > the Steam Client and all seems to go just fine. I think that there is a lot of
> >> > Linux out of the desktop that could use this driver and cannot use the Steam
> >> > Client. Worst case scenario, this driver can now be blacklisted, but I hope
> >> > that will not be needed.
> >>
> >> I tested the driver with my 4.15 fedora kernel (I only built the
> >> module not the whole kernel) and I got double inputs (your driver
> >> input device + steam uinput device) when testing Shovel Knight with
> >> Steam Big Picture. It seems to work fine when the inputs are the same,
> >> but after changing the controller configuration in Steam, the issue
> >> became apparent.
> >
> > I assumed that when several joysticks are available, games would listen
> > to one one of them. It looks like I'm wrong, and some (many?) games will
> > listen to all available joysticks at the same time. Thus having two
> > logical joysticks that represent the same physical one is not good.
> 
> Yeah, the general rule of thumb is "think of the worst thing that can
> happen, someone will do something worst".
> 
> >
> > An easy solution would be that Steam Client grabs this driver
> > (ioctl(EVIOCGRAB)) when creating the uinput device. Another solution
> > would be that Steam Client blacklists this driver, of course.
> 
> This is 2 solutions that rely on a userspace change, and this is not
> acceptable in its current form. What if people do not upgrade Steam
> client but upgrade their kernel? Well, Steam might be able to force
> people to always run the latest shiny available version, but for other
> games, you can't expect people to have a compatible version of the
> userspace stack.

Well, if you don't have Steam then you don't have the double input in
the first place. Unless you are using a different user-mode driver, of
course.
> 
> Also, "blacklisting the driver" from Steam client is something the OS
> can do, but not the client when you run on a different distribution.
> You need root for that, and I don't want to give root permissions to
> Steam (or to any user space client that shouldn't have root privileges
> for what it matters).

Actually Steam needs a system installation that adds udev rules to grant
uaccess to /dev/uinput and the USB raw device for the controller.
Adding a /etc/modprobe.d/steam.conf should be possible, too. It would be
a bit inconvenient because you'll need a distro update of the steam
package, not just the usual user-mode-only auto-update.

> >
> >> And without Steam and your external tool, you get double inputs too. I
> >> tried RetroArch and it was unusable because of the keyboard inputs
> >> from the lizard mode (e.g. pressing B also presses Esc and quits
> >> RetroArch). Having to download and compile an external tool to make
> >> the driver work properly may be too difficult for the user. Your goal
> >> was to provide an alternative to user space drivers but now you
> >> actually depend on (a very simple) one.
> >
> > Yes, I noticed that. TBH, this driver without Steam Client or the
> > user-space tool is not very nice, precisely because you'll get constant
> > Escape and Enter presses, and most games react to those.
> >
> > Frankly speaking, I'm not sure how to proceed. I can think of the
> > following options:
> >  1.Steam Client installation could add a file to blacklist
> >    hid-steam, just as it adds a few udev rules.
> 
> But what about RetroArch? And what if you install Steam but want to
> play SDL games that could benefit from your driver?

That is an issue of solution 1. I actually have the module blacklisted
in my PC, and run `sudo modprobe hid-steam` to use SDL.

> >  2.The default CONFIG_HID_STEAM can be changed to "n". Maybe only
> >    on the architectures for which there is a Steam Client available.
> >    This way DIY projects will still be able to use it.
> 
> But this will make the decision to include or not the driver in
> distributions harder. And if no distribution uses it, you won't have
> free tests, and you will be alone to maintain it. So that's not ideal
> either

Could we set the default to 'y' in non-PC systems. It would be enabled
in my Raspbian, for example... better than nothing.
> 
> >  3.This driver could be abandoned :-(. Just use Steam Client if possible or
> >    any of the user-mode drivers available.
> 
> This would be a waste for everybody as it's always better when we share.

Indeed!

I tried a new option:
  4. The driver detects whether the DEVUSB/HIDRAW device is in use, and
     if that is the case it will disable itself. If the DEVUSB/HIDRAW is
     not in use, then the driver will work normally. A bit hackish maybe
     but it should work.

I tried doing this option 4, but I'm unable to do it properly. I don't
even know if it is possible...

> >
> > If we decide for 1 or 2, then the lizard mode could be disabled without
> > ill effects. We could even enable the gyro and all the other gadgets
> > without worring about current compatibility.
> 
> To me, 1 is out of the question. The kernel can't expect a user space
> change especially if you are knowingly introducing a bug for the end
> user.
> 
> 2 is still on the table IMO, and 3 would be a shame.
> 
> I know we already discussed about sysfs and module parameters, but if
> the driver will conflict with a userspace stack, the only way would be
> to have a (dynamic) parameter "enhanced_mode" or
> "kernel_awesome_support" or whatever which would be a boolean, that
> defaults to false that Steam can eventually lookup if they want so in
> the future we can default it to true. When this parameter is set, the
> driver will create the inputs and toggle the various modes, while when
> it's toggled off, it'll clean up itself and keep the device as if it
> were connected to hid-generic. Bonus point, this removes the need for
> the simple user space tool that enables the mode.

That is doable, but that sysfs/parameter can be changed by a non-root
user? I looked for a udev rule to grant access to those but found
nothing.

IIUC, when this parameter is false the driver will do nothing, right?
The user will just need to change it to true to be able to use it, but
that will have to be done by root.

I'll try doing this, but I'd appreciate your advice about what approach
would be better: sysfs? a module parameter? a cdev? or even a EV_MSC?

> > At the end of the day, I think that it is up to Valve what to do.
> 
> Again, Valve is a big player here, but do not underestimate other
> projects (like RetroArch mentioned above) because if you break their
> workflow, they will have the right to request a revert of the commit
> because it breaks some random user playing games in the far end of
> Antarctica (yes, penguins do love to play games :-P )

And everybody loves penguins! If we take away Steam (say a RaspberryPi
as a canonical example) and disable the lizard mode, then this driver is
just a regular gamepad. RetroArch should be happy with that. Unless they
already have an user mode driver for the steam-controller, of course...

Best regards.
Rodrigo

> Cheers,
> Benjamin
> 
> > Best Regards.
> > Rodrigo.
> >
> >> Also the button and axis codes do not match the gamepad API doc
> >> (https://www.kernel.org/doc/Documentation/input/gamepad.txt).
> >>
> >> >
> >> > For full reference, I'm adding a full changelog of this patchset.
> >> >
> >> > Changes in v5:
> >> >  * Fix license SPDX to GPL-2.0+.
> >> >  * Minor stylistic changes (BIT(3) instead 0x08 and so on).
> >> >
> >> > Changes in v4:
> >> >  * Add command to check the wireless connection status on probe, without
> >> >    waiting for a message (thanks to Clément Vuchener for the tip).
> >> >  * Removed the error code on redundant connection/disconnection messages. That
> >> >    was harmless but polluted dmesg.
> >> >  * Added buttons for touching the left-pad and right-pad.
> >> >  * Fixed a misplaced #include from 2/4 to 1/4.
> >> >
> >> > Changes in v3:
> >> >  * Use RCU to do the dynamic connec/disconnect of wireless devices.
> >> >  * Remove entries in hid-quirks.c as they are no longer needed. This allows
> >> >    this module to be blacklisted without side effects.
> >> >  * Do not bypass the virtual keyboard/mouse HID devices to avoid breaking
> >> >    existing use cases (lizard mode). A user-space tool to do that is
> >> >    linked.
> >> >  * Fully separated axes for joystick and left-pad. As it happens.
> >> >  * Add fuzz values for left/right pad axes, they are a little wiggly.
> >> >
> >> > Changes in v2:
> >> >  * Remove references to USB. Now the interesting interfaces are selected by
> >> >    looking for the ones with feature reports.
> >> >  * Feature reports buffers are allocated with hid_alloc_report_buf().
> >> >  * Feature report length is checked, to avoid overflows in case of
> >> >    corrupt/malicius USB devices.
> >> >  * Resolution added to the ABS axes.
> >> >  * A lot of minor cleanups.
> >> >
> >> > Rodrigo Rivas Costa (4):
> >> >   HID: add driver for Valve Steam Controller
> >> >   HID: steam: add serial number information.
> >> >   HID: steam: command to check wireless connection
> >> >   HID: steam: add battery device.
> >> >
> >> >  drivers/hid/Kconfig     |   8 +
> >> >  drivers/hid/Makefile    |   1 +
> >> >  drivers/hid/hid-ids.h   |   4 +
> >> >  drivers/hid/hid-steam.c | 794 ++++++++++++++++++++++++++++++++++++++++++++++++
> >> >  4 files changed, 807 insertions(+)
> >> >  create mode 100644 drivers/hid/hid-steam.c
> >> >
> >> > --
> >> > 2.16.2
> >> >

^ permalink raw reply

* [PATCH v4 2/2] Remove false-positive VLAs when using max()
From: Kees Cook @ 2018-03-15 19:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott,
	linux-input, linux-btrfs, netdev, linux-kernel, kernel-hardening
In-Reply-To: <1521143266-31350-1-git-send-email-keescook@chromium.org>

As part of removing VLAs from the kernel[1], we want to build with -Wvla,
but it is overly pessimistic and only accepts constant expressions for
stack array sizes, instead of also constant values. The max() macro
triggers the warning, so this refactors these uses of max() to use the
new const_max() instead.

[1] https://lkml.org/lkml/2018/3/7/621

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/input/touchscreen/cyttsp4_core.c |  2 +-
 fs/btrfs/tree-checker.c                  |  3 ++-
 lib/vsprintf.c                           |  4 ++--
 net/ipv4/proc.c                          |  8 ++++----
 net/ipv6/proc.c                          | 10 ++++------
 5 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c
index 727c3232517c..f89497940051 100644
--- a/drivers/input/touchscreen/cyttsp4_core.c
+++ b/drivers/input/touchscreen/cyttsp4_core.c
@@ -868,7 +868,7 @@ static void cyttsp4_get_mt_touches(struct cyttsp4_mt_data *md, int num_cur_tch)
 	struct cyttsp4_touch tch;
 	int sig;
 	int i, j, t = 0;
-	int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
+	int ids[const_max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)];
 
 	memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int));
 	for (i = 0; i < num_cur_tch; i++) {
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index c3c8d48f6618..1ddd6cc3c4fc 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -341,7 +341,8 @@ static int check_dir_item(struct btrfs_root *root,
 		 */
 		if (key->type == BTRFS_DIR_ITEM_KEY ||
 		    key->type == BTRFS_XATTR_ITEM_KEY) {
-			char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)];
+			char namebuf[const_max(BTRFS_NAME_LEN,
+					       XATTR_NAME_MAX)];
 
 			read_extent_buffer(leaf, namebuf,
 					(unsigned long)(di + 1), name_len);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d7a708f82559..9d5610b643ce 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -744,8 +744,8 @@ char *resource_string(char *buf, char *end, struct resource *res,
 #define FLAG_BUF_SIZE		(2 * sizeof(res->flags))
 #define DECODED_BUF_SIZE	sizeof("[mem - 64bit pref window disabled]")
 #define RAW_BUF_SIZE		sizeof("[mem - flags 0x]")
-	char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
-		     2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
+	char sym[const_max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE,
+			   2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)];
 
 	char *p = sym, *pend = sym + sizeof(sym);
 	int decode = (fmt[0] == 'R') ? 1 : 0;
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index dc5edc8f7564..fad6f989004e 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -46,7 +46,7 @@
 #include <net/sock.h>
 #include <net/raw.h>
 
-#define TCPUDP_MIB_MAX max_t(u32, UDP_MIB_MAX, TCP_MIB_MAX)
+#define TCPUDP_MIB_MAX const_max(UDP_MIB_MAX, TCP_MIB_MAX)
 
 /*
  *	Report socket allocation statistics [mea@utu.fi]
@@ -404,7 +404,7 @@ static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v)
 	struct net *net = seq->private;
 	int i;
 
-	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
+	memset(buff, 0, sizeof(buff));
 
 	seq_puts(seq, "\nTcp:");
 	for (i = 0; snmp4_tcp_list[i].name; i++)
@@ -421,7 +421,7 @@ static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v)
 			seq_printf(seq, " %lu", buff[i]);
 	}
 
-	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
+	memset(buff, 0, sizeof(buff));
 
 	snmp_get_cpu_field_batch(buff, snmp4_udp_list,
 				 net->mib.udp_statistics);
@@ -432,7 +432,7 @@ static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v)
 	for (i = 0; snmp4_udp_list[i].name; i++)
 		seq_printf(seq, " %lu", buff[i]);
 
-	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
+	memset(buff, 0, sizeof(buff));
 
 	/* the UDP and UDP-Lite MIBs are the same */
 	seq_puts(seq, "\nUdpLite:");
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index b67814242f78..58bbfc4fa7fa 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -30,10 +30,8 @@
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 
-#define MAX4(a, b, c, d) \
-	max_t(u32, max_t(u32, a, b), max_t(u32, c, d))
-#define SNMP_MIB_MAX MAX4(UDP_MIB_MAX, TCP_MIB_MAX, \
-			IPSTATS_MIB_MAX, ICMP_MIB_MAX)
+#define SNMP_MIB_MAX const_max(const_max(UDP_MIB_MAX, TCP_MIB_MAX), \
+			       const_max(IPSTATS_MIB_MAX, ICMP_MIB_MAX))
 
 static int sockstat6_seq_show(struct seq_file *seq, void *v)
 {
@@ -199,7 +197,7 @@ static void snmp6_seq_show_item(struct seq_file *seq, void __percpu *pcpumib,
 	int i;
 
 	if (pcpumib) {
-		memset(buff, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
+		memset(buff, 0, sizeof(buff));
 
 		snmp_get_cpu_field_batch(buff, itemlist, pcpumib);
 		for (i = 0; itemlist[i].name; i++)
@@ -218,7 +216,7 @@ static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu *mib,
 	u64 buff64[SNMP_MIB_MAX];
 	int i;
 
-	memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
+	memset(buff64, 0, sizeof(buff64));
 
 	snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
 	for (i = 0; itemlist[i].name; i++)
-- 
2.7.4


^ permalink raw reply related

* [PATCH v4 1/2] kernel.h: Introduce const_max() for VLA removal
From: Kees Cook @ 2018-03-15 19:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott,
	linux-input, linux-btrfs, netdev, linux-kernel, kernel-hardening
In-Reply-To: <1521143266-31350-1-git-send-email-keescook@chromium.org>

In the effort to remove all VLAs from the kernel[1], it is desirable to
build with -Wvla. However, this warning is overly pessimistic, in that
it is only happy with stack array sizes that are declared as constant
expressions, and not constant values. One case of this is the evaluation
of the max() macro which, due to its construction, ends up converting
constant expression arguments into a constant value result. Attempts
to adjust the behavior of max() ran afoul of version-dependent compiler
behavior[2].

To work around this and still gain -Wvla coverage, this patch introduces
a new macro, const_max(), for use in these cases of stack array size
declaration, where the constant expressions are retained. Since this means
losing the double-evaluation protections of the max() macro, this macro is
designed to explicitly fail if used on non-constant arguments.

Older compilers will fail with the unhelpful message:

    error: first argument to ‘__builtin_choose_expr’ not a constant

Newer compilers will fail with a hopefully more helpful message:

    error: call to ‘__error_not_const_arg’ declared with attribute error: const_max() used with non-compile-time constant arg

To gain the ability to compare differing types, the arguments are
explicitly cast to size_t. Without this, some compiler versions will
fail when comparing different enum types or similar constant expression
cases. With the casting, it's possible to do things like:

    int foo[const_max(6, sizeof(something))];

[1] https://lkml.org/lkml/2018/3/7/621
[2] https://lkml.org/lkml/2018/3/10/170

Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/kernel.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3fd291503576..012f588b5a25 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -820,6 +820,25 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
 	      x, y)
 
 /**
+ * const_max - return maximum of two positive compile-time constant values
+ * @x: first compile-time constant value
+ * @y: second compile-time constant value
+ *
+ * This has no type checking nor multi-evaluation defenses, and must
+ * only ever be used with positive compile-time constant values (for
+ * example when calculating a stack array size).
+ */
+size_t __error_not_const_arg(void) \
+__compiletime_error("const_max() used with non-compile-time constant arg");
+#define const_max(x, y)						\
+	__builtin_choose_expr(__builtin_constant_p(x) &&	\
+			      __builtin_constant_p(y),		\
+			      (size_t)(x) > (size_t)(y) ?	\
+					(size_t)(x) :		\
+					(size_t)(y),		\
+			      __error_not_const_arg())
+
+/**
  * min3 - return minimum of three values
  * @x: first value
  * @y: second value
-- 
2.7.4

^ permalink raw reply related

* [PATCH v4 0/2] Remove false-positive VLAs when using max()
From: Kees Cook @ 2018-03-15 19:47 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kees Cook, Linus Torvalds, Josh Poimboeuf, Rasmus Villemoes,
	Randy Dunlap, Miguel Ojeda, Ingo Molnar, David Laight, Ian Abbott,
	linux-input, linux-btrfs, netdev, linux-kernel, kernel-hardening

I'm calling this "v4" since the last effort at this was v3, even
if it's a different approach. Patch 1 adds const_max(), patch 2
uses it in all the places max() was used for stack arrays. Commit
log from patch 1:

---snip---
kernel.h: Introduce const_max() for VLA removal

In the effort to remove all VLAs from the kernel[1], it is desirable to
build with -Wvla. However, this warning is overly pessimistic, in that
it is only happy with stack array sizes that are declared as constant
expressions, and not constant values. One case of this is the evaluation
of the max() macro which, due to its construction, ends up converting
constant expression arguments into a constant value result. Attempts
to adjust the behavior of max() ran afoul of version-dependent compiler
behavior[2].

To work around this and still gain -Wvla coverage, this patch introduces
a new macro, const_max(), for use in these cases of stack array size
declaration, where the constant expressions are retained. Since this means
losing the double-evaluation protections of the max() macro, this macro is
designed to explicitly fail if used on non-constant arguments.

Older compilers will fail with the unhelpful message:

    error: first argument to ‘__builtin_choose_expr’ not a constant

Newer compilers will fail with a hopefully more helpful message:

    error: call to ‘__error_not_const_arg’ declared with attribute error: const_max() used with non-compile-time constant arg

To gain the ability to compare differing types, the arguments are
explicitly cast to size_t. Without this, some compiler versions will
fail when comparing different enum types or similar constant expression
cases. With the casting, it's possible to do things like:

int foo[const_max(6, sizeof(something))];

[1] https://lkml.org/lkml/2018/3/7/621
[2] https://lkml.org/lkml/2018/3/10/170
---eol---

Hopefully this reads well as a summary from all the things that got tried.
I've tested this on allmodconfig builds with gcc 4.4.4 and 6.3.0, with and
without -Wvla.

-Kees

^ permalink raw reply

* Re: rfc: remove print_vma_addr ? (was Re: [PATCH 00/16] remove eight obsolete architectures)
From: Joe Perches @ 2018-03-15 17:13 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Linux-Arch, linux-block, Linux Fbdev development list,
	Linux Watchdog Mailing List, Arnd Bergmann, linux-doc, netdev,
	USB list, linux-wireless, Linux Kernel Mailing List,
	Linux PWM List, linux-spi, David Howells, linux-ide,
	Geert Uytterhoeven, DRI Development, linux-input, Linux FS Devel,
	Linux MM, linux-rtc
In-Reply-To: <20180315170830.GA17574@bombadil.infradead.org>

On Thu, 2018-03-15 at 10:08 -0700, Matthew Wilcox wrote:
> On Thu, Mar 15, 2018 at 09:56:46AM -0700, Joe Perches wrote:
> > I have a patchset that creates a vsprintf extension for
> > print_vma_addr and removes all the uses similar to the
> > print_symbol() removal.
> > 
> > This now avoids any possible printk interleaving.
> > 
> > Unfortunately, without some #ifdef in vsprintf, which
> > I would like to avoid, it increases the nommu kernel
> > size by ~500 bytes.
> > 
> > Anyone think this is acceptable?
[]
> This doesn't feel like a huge win since it's only called ~once per
> architecture.  I'd be more excited if it made the printing of the whole
> thing standardised; eg we have a print_fault() function in mm/memory.c
> which takes a suitable set of arguments.

Sure but perhaps that's not feasible as the surrounding output
is per-arch specific.

What could be a standardized fault message here?

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: rfc: remove print_vma_addr ? (was Re: [PATCH 00/16] remove eight obsolete architectures)
From: Matthew Wilcox @ 2018-03-15 17:08 UTC (permalink / raw)
  To: Joe Perches
  Cc: Geert Uytterhoeven, David Howells, Arnd Bergmann, Linux-Arch,
	Linux Kernel Mailing List, linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA,
	linux-ide-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA, netdev, linux-wireless,
	Linux PWM List, linux-rtc-u79uwXL29TY76Z2rM5mHXA, linux-spi,
	USB list, DRI Development, Linux Fbdev development list,
	Linux Watchdog Mailing List, Linux FS Devel
In-Reply-To: <1521133006.22221.35.camel-6d6DIl74uiNBDgjK7y7TUQ@public.gmane.org>

On Thu, Mar 15, 2018 at 09:56:46AM -0700, Joe Perches wrote:
> I have a patchset that creates a vsprintf extension for
> print_vma_addr and removes all the uses similar to the
> print_symbol() removal.
> 
> This now avoids any possible printk interleaving.
> 
> Unfortunately, without some #ifdef in vsprintf, which
> I would like to avoid, it increases the nommu kernel
> size by ~500 bytes.
> 
> Anyone think this is acceptable?
> 
> Here's the overall patch, but I have it as a series
> ---
>  Documentation/core-api/printk-formats.rst |  9 +++++
>  arch/arm64/kernel/traps.c                 | 13 +++----
>  arch/mips/mm/fault.c                      | 16 ++++-----
>  arch/parisc/mm/fault.c                    | 15 ++++----
>  arch/riscv/kernel/traps.c                 | 11 +++---
>  arch/s390/mm/fault.c                      |  7 ++--
>  arch/sparc/mm/fault_32.c                  |  8 ++---
>  arch/sparc/mm/fault_64.c                  |  8 ++---
>  arch/tile/kernel/signal.c                 |  9 ++---
>  arch/um/kernel/trap.c                     | 13 +++----
>  arch/x86/kernel/signal.c                  | 10 ++----
>  arch/x86/kernel/traps.c                   | 18 ++++------
>  arch/x86/mm/fault.c                       | 12 +++----
>  include/linux/mm.h                        |  1 -
>  lib/vsprintf.c                            | 58 ++++++++++++++++++++++++++-----
>  mm/memory.c                               | 33 ------------------
>  16 files changed, 112 insertions(+), 129 deletions(-)

This doesn't feel like a huge win since it's only called ~once per
architecture.  I'd be more excited if it made the printing of the whole
thing standardised; eg we have a print_fault() function in mm/memory.c
which takes a suitable set of arguments.

^ permalink raw reply

* rfc: remove print_vma_addr ? (was Re: [PATCH 00/16] remove eight obsolete architectures)
From: Joe Perches @ 2018-03-15 16:56 UTC (permalink / raw)
  To: Geert Uytterhoeven, David Howells
  Cc: Linux-Arch, Linux PWM List, Linux Fbdev development list,
	Linux Watchdog Mailing List, Arnd Bergmann, linux-doc, netdev,
	USB list, linux-wireless, Linux Kernel Mailing List,
	DRI Development, linux-spi, linux-block, linux-ide, linux-input,
	Linux FS Devel, Linux MM, linux-rtc
In-Reply-To: <CAMuHMdXcxuzCOnFCNm4NXDv-wfYJDO5GQpB_ECu7j=2BjMhNpA@mail.gmail.com>

On Thu, 2018-03-15 at 10:48 +0100, Geert Uytterhoeven wrote:
> Hi David,
> 
> On Thu, Mar 15, 2018 at 10:42 AM, David Howells <dhowells@redhat.com> wrote:
> > Do we have anything left that still implements NOMMU?
> 
> Sure: arm, c6x, m68k, microblaze, and  sh.

I have a patchset that creates a vsprintf extension for
print_vma_addr and removes all the uses similar to the
print_symbol() removal.

This now avoids any possible printk interleaving.

Unfortunately, without some #ifdef in vsprintf, which
I would like to avoid, it increases the nommu kernel
size by ~500 bytes.

Anyone think this is acceptable?

Here's the overall patch, but I have it as a series
---
 Documentation/core-api/printk-formats.rst |  9 +++++
 arch/arm64/kernel/traps.c                 | 13 +++----
 arch/mips/mm/fault.c                      | 16 ++++-----
 arch/parisc/mm/fault.c                    | 15 ++++----
 arch/riscv/kernel/traps.c                 | 11 +++---
 arch/s390/mm/fault.c                      |  7 ++--
 arch/sparc/mm/fault_32.c                  |  8 ++---
 arch/sparc/mm/fault_64.c                  |  8 ++---
 arch/tile/kernel/signal.c                 |  9 ++---
 arch/um/kernel/trap.c                     | 13 +++----
 arch/x86/kernel/signal.c                  | 10 ++----
 arch/x86/kernel/traps.c                   | 18 ++++------
 arch/x86/mm/fault.c                       | 12 +++----
 include/linux/mm.h                        |  1 -
 lib/vsprintf.c                            | 58 ++++++++++++++++++++++++++-----
 mm/memory.c                               | 33 ------------------
 16 files changed, 112 insertions(+), 129 deletions(-)

diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index 934559b3c130..10a91da1bc83 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -157,6 +157,15 @@ DMA address types dma_addr_t
 For printing a dma_addr_t type which can vary based on build options,
 regardless of the width of the CPU data path.
 
+VMA name and address
+----------------------------
+
+::
+
+	%pav	<name>[hexstart+hexsize] or ?[0+0] if unavailable
+
+For any address, print the vma's name and its starting address and size
+
 Passed by reference.
 
 Raw buffer as an escaped string
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 2b478565d774..48edf812ce8b 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -242,13 +242,14 @@ void arm64_force_sig_info(struct siginfo *info, const char *str,
 	if (!show_unhandled_signals_ratelimited())
 		goto send_sig;
 
-	pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk));
 	if (esr)
-		pr_cont("%s, ESR 0x%08x, ", esr_get_class_string(esr), esr);
-
-	pr_cont("%s", str);
-	print_vma_addr(KERN_CONT " in ", regs->pc);
-	pr_cont("\n");
+		pr_info("%s[%d]: unhandled exception: %s, ESR 0x%08x, %s in %pav\n",
+			tsk->comm, task_pid_nr(tsk),
+			esr_get_class_string(esr), esr,
+			str, &regs->pc);
+	else
+		pr_info("%s[%d]: unhandled exception: %s in %pav\n",
+			tsk->comm, task_pid_nr(tsk), str, &regs->pc);
 	__show_regs(regs);
 
 send_sig:
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 4f8f5bf46977..ce7bf077a0f5 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -213,14 +213,14 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
 				tsk->comm,
 				write ? "write access to" : "read access from",
 				field, address);
-			pr_info("epc = %0*lx in", field,
-				(unsigned long) regs->cp0_epc);
-			print_vma_addr(KERN_CONT " ", regs->cp0_epc);
-			pr_cont("\n");
-			pr_info("ra  = %0*lx in", field,
-				(unsigned long) regs->regs[31]);
-			print_vma_addr(KERN_CONT " ", regs->regs[31]);
-			pr_cont("\n");
+			pr_info("epc = %0*lx in %pav\n",
+				field,
+				(unsigned long)regs->cp0_epc,
+				&regs->cp0_epc);
+			pr_info("ra  = %0*lx in %pav\n",
+				field,
+				(unsigned long)regs->regs[31],
+				&regs->regs[31]);
 		}
 		current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
 		info.si_signo = SIGSEGV;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index e247edbca68e..877cea702714 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -240,17 +240,14 @@ show_signal_msg(struct pt_regs *regs, unsigned long code,
 	if (!printk_ratelimit())
 		return;
 
-	pr_warn("\n");
-	pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx",
-	    tsk->comm, code, address);
-	print_vma_addr(KERN_CONT " in ", regs->iaoq[0]);
-
-	pr_cont("\ntrap #%lu: %s%c", code, trap_name(code),
-		vma ? ',':'\n');
+	pr_warn("do_page_fault() command='%s' type=%lu address=0x%08lx in %pav\n",
+		tsk->comm, code, address, &regs->iaoq[0]);
 
 	if (vma)
-		pr_cont(" vm_start = 0x%08lx, vm_end = 0x%08lx\n",
-			vma->vm_start, vma->vm_end);
+		pr_warn("trap #%lu: %s%c, vm_start = 0x%08lx, vm_end = 0x%08lx\n",
+			code, trap_name(code), vma->vm_start, vma->vm_end);
+	else
+		pr_warn("trap #%lu: %s%c\n", code, trap_name(code));
 
 	show_regs(regs);
 }
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 93132cb59184..16609dcb2546 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -78,12 +78,11 @@ static inline void do_trap_siginfo(int signo, int code,
 void do_trap(struct pt_regs *regs, int signo, int code,
 	unsigned long addr, struct task_struct *tsk)
 {
-	if (show_unhandled_signals && unhandled_signal(tsk, signo)
-	    && printk_ratelimit()) {
-		pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT,
-			tsk->comm, task_pid_nr(tsk), signo, code, addr);
-		print_vma_addr(KERN_CONT " in ", GET_IP(regs));
-		pr_cont("\n");
+	if (show_unhandled_signals && unhandled_signal(tsk, signo) &&
+	    printk_ratelimit()) {
+		pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT " in %pav\n",
+			tsk->comm, task_pid_nr(tsk), signo, code, addr,
+			&GET_IP(regs));
 		show_regs(regs);
 	}
 
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 93faeca52284..3b1d6d618af2 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -250,10 +250,9 @@ void report_user_fault(struct pt_regs *regs, long signr, int is_mm_fault)
 		return;
 	if (!printk_ratelimit())
 		return;
-	printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ",
-	       regs->int_code & 0xffff, regs->int_code >> 17);
-	print_vma_addr(KERN_CONT "in ", regs->psw.addr);
-	printk(KERN_CONT "\n");
+	printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d in %pav\n",
+	       regs->int_code & 0xffff, regs->int_code >> 17,
+	       &regs->psw.addr);
 	if (is_mm_fault)
 		dump_fault_info(regs);
 	show_regs(regs);
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index a8103a84b4ac..206ec5a1c915 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -113,15 +113,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
 	if (!printk_ratelimit())
 		return;
 
-	printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x",
+	printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x in %pav\n",
 	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
 	       tsk->comm, task_pid_nr(tsk), address,
 	       (void *)regs->pc, (void *)regs->u_regs[UREG_I7],
-	       (void *)regs->u_regs[UREG_FP], code);
-
-	print_vma_addr(KERN_CONT " in ", regs->pc);
-
-	printk(KERN_CONT "\n");
+	       (void *)regs->u_regs[UREG_FP], code, &regs->pc);
 }
 
 static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs,
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 41363f46797b..a21199329ebe 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -154,15 +154,11 @@ show_signal_msg(struct pt_regs *regs, int sig, int code,
 	if (!printk_ratelimit())
 		return;
 
-	printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x",
+	printk("%s%s[%d]: segfault at %lx ip %px (rpc %px) sp %px error %x in %pav\b",
 	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
 	       tsk->comm, task_pid_nr(tsk), address,
 	       (void *)regs->tpc, (void *)regs->u_regs[UREG_I7],
-	       (void *)regs->u_regs[UREG_FP], code);
-
-	print_vma_addr(KERN_CONT " in ", regs->tpc);
-
-	printk(KERN_CONT "\n");
+	       (void *)regs->u_regs[UREG_FP], code, &regs->tpc);
 }
 
 static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index f2bf557bb005..0556106dfe8a 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -383,13 +383,10 @@ void trace_unhandled_signal(const char *type, struct pt_regs *regs,
 	if (show_unhandled_signals <= 1 && !printk_ratelimit())
 		return;
 
-	printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d",
+	printk("%s%s[%d]: %s at %lx pc " REGFMT " signal %d in %pav\n",
 	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-	       tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig);
-
-	print_vma_addr(KERN_CONT " in ", regs->pc);
-
-	printk(KERN_CONT "\n");
+	       tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig,
+	       &regs->pc);
 
 	if (show_unhandled_signals > 1) {
 		switch (sig) {
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index b2b02df9896e..9281248972c0 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -150,14 +150,11 @@ static void show_segv_info(struct uml_pt_regs *regs)
 	if (!printk_ratelimit())
 		return;
 
-	printk("%s%s[%d]: segfault at %lx ip %px sp %px error %x",
-		task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-		tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi),
-		(void *)UPT_IP(regs), (void *)UPT_SP(regs),
-		fi->error_code);
-
-	print_vma_addr(KERN_CONT " in ", UPT_IP(regs));
-	printk(KERN_CONT "\n");
+	printk("%s%s[%d]: segfault at %lx ip %px sp %px error %x in %pav\n",
+	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+	       tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi),
+	       (void *)UPT_IP(regs), (void *)UPT_SP(regs),
+	       fi->error_code, &UPT_IP(regs));
 }
 
 static void bad_segv(struct faultinfo fi, unsigned long ip)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 4cdc0b27ec82..9ab0c5c50b29 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -841,15 +841,11 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
 {
 	struct task_struct *me = current;
 
-	if (show_unhandled_signals && printk_ratelimit()) {
-		printk("%s"
-		       "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
+	if (show_unhandled_signals && printk_ratelimit())
+		printk("%s%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx in %pav\n",
 		       task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
 		       me->comm, me->pid, where, frame,
-		       regs->ip, regs->sp, regs->orig_ax);
-		print_vma_addr(KERN_CONT " in ", regs->ip);
-		pr_cont("\n");
-	}
+		       regs->ip, regs->sp, regs->orig_ax, &regs->ip);
 
 	force_sig(SIGSEGV, me);
 }
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 3d9b2308e7fa..c6e3d02759e5 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -270,13 +270,10 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
 	tsk->thread.trap_nr = trapnr;
 
 	if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
-	    printk_ratelimit()) {
-		pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx",
+	    printk_ratelimit())
+		pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx in %pav\n",
 			tsk->comm, tsk->pid, str,
-			regs->ip, regs->sp, error_code);
-		print_vma_addr(KERN_CONT " in ", regs->ip);
-		pr_cont("\n");
-	}
+			regs->ip, regs->sp, error_code, &regs->ip);
 
 	force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk);
 }
@@ -565,13 +562,10 @@ do_general_protection(struct pt_regs *regs, long error_code)
 	tsk->thread.trap_nr = X86_TRAP_GP;
 
 	if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
-			printk_ratelimit()) {
-		pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx",
+			printk_ratelimit())
+		pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx in %pav\n",
 			tsk->comm, task_pid_nr(tsk),
-			regs->ip, regs->sp, error_code);
-		print_vma_addr(KERN_CONT " in ", regs->ip);
-		pr_cont("\n");
-	}
+			regs->ip, regs->sp, error_code, &regs->ip);
 
 	force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk);
 }
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e6af2b464c3d..b629319e621a 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -857,14 +857,10 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
 	if (!printk_ratelimit())
 		return;
 
-	printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx",
-		task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
-		tsk->comm, task_pid_nr(tsk), address,
-		(void *)regs->ip, (void *)regs->sp, error_code);
-
-	print_vma_addr(KERN_CONT " in ", regs->ip);
-
-	printk(KERN_CONT "\n");
+	printk("%s%s[%d]: segfault at %lx ip %px sp %px error %lx in %pav\n",
+	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+	       tsk->comm, task_pid_nr(tsk), address,
+	       (void *)regs->ip, (void *)regs->sp, error_code, &regs->ip);
 }
 
 static void
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 9f1270360983..9584bd3e8c25 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2537,7 +2537,6 @@ extern int randomize_va_space;
 #endif
 
 const char * arch_vma_name(struct vm_area_struct *vma);
-void print_vma_addr(char *prefix, unsigned long rip);
 
 void sparse_mem_maps_populate_node(struct page **map_map,
 				   unsigned long pnum_begin,
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 942b5234a59b..9081476ea4ea 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -35,6 +35,8 @@
 #include <net/addrconf.h>
 #include <linux/siphash.h>
 #include <linux/compiler.h>
+#include <linux/mm_types.h>
+
 #ifdef CONFIG_BLOCK
 #include <linux/blkdev.h>
 #endif
@@ -407,6 +409,11 @@ struct printf_spec {
 #define FIELD_WIDTH_MAX ((1 << 23) - 1)
 #define PRECISION_MAX ((1 << 15) - 1)
 
+static const struct printf_spec strspec = {
+	.field_width = -1,
+	.precision = -1,
+};
+
 static noinline_for_stack
 char *number(char *buf, char *end, unsigned long long num,
 	     struct printf_spec spec)
@@ -1427,6 +1434,45 @@ char *netdev_bits(char *buf, char *end, const void *addr, const char *fmt)
 	return special_hex_number(buf, end, num, size);
 }
 
+static noinline_for_stack
+char *vma_addr(char *buf, char *end, const void *addr)
+{
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+	char *page;
+	char tbuf[2 * sizeof(unsigned long) * 2 + 4];
+	const char *output = "?[0+0]";
+
+	/*
+	 * we might be running from an atomic context so we cannot sleep
+	 */
+	if (!down_read_trylock(&mm->mmap_sem))
+		goto output;
+
+	vma = find_vma(mm, *(unsigned long *)addr);
+	if (!vma || !vma->vm_file)
+		goto up_read;
+
+	page = (char *)__get_free_page(GFP_ATOMIC | __GFP_NOWARN);
+	if (page) {
+		char *fp;
+
+		fp = file_path(vma->vm_file, page, PAGE_SIZE);
+		if (IS_ERR(fp))
+			fp = "?";
+		buf = string(buf, end, kbasename(fp), strspec);
+		sprintf(tbuf, "[%lx+%lx]",
+			vma->vm_start, vma->vm_end - vma->vm_start);
+		output = tbuf;
+		free_page((unsigned long)page);
+	}
+
+up_read:
+	up_read(&mm->mmap_sem);
+output:
+	return string(buf, end, output, strspec);
+}
+
 static noinline_for_stack
 char *address_val(char *buf, char *end, const void *addr, const char *fmt)
 {
@@ -1434,6 +1480,8 @@ char *address_val(char *buf, char *end, const void *addr, const char *fmt)
 	int size;
 
 	switch (fmt[1]) {
+	case 'v':
+		return vma_addr(buf, end, addr);
 	case 'd':
 		num = *(const dma_addr_t *)addr;
 		size = sizeof(dma_addr_t);
@@ -1474,11 +1522,7 @@ char *format_flags(char *buf, char *end, unsigned long flags,
 					const struct trace_print_flags *names)
 {
 	unsigned long mask;
-	const struct printf_spec strspec = {
-		.field_width = -1,
-		.precision = -1,
-	};
-	const struct printf_spec numspec = {
+	static const struct printf_spec numspec = {
 		.flags = SPECIAL|SMALL,
 		.field_width = -1,
 		.precision = -1,
@@ -1548,10 +1592,6 @@ char *device_node_gen_full_name(const struct device_node *np, char *buf, char *e
 {
 	int depth;
 	const struct device_node *parent = np->parent;
-	static const struct printf_spec strspec = {
-		.field_width = -1,
-		.precision = -1,
-	};
 
 	/* special case for root node */
 	if (!parent)
diff --git a/mm/memory.c b/mm/memory.c
index bc760df8a7f4..f1f922421bde 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4502,39 +4502,6 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,
 }
 EXPORT_SYMBOL_GPL(access_process_vm);
 
-/*
- * Print the name of a VMA.
- */
-void print_vma_addr(char *prefix, unsigned long ip)
-{
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-
-	/*
-	 * we might be running from an atomic context so we cannot sleep
-	 */
-	if (!down_read_trylock(&mm->mmap_sem))
-		return;
-
-	vma = find_vma(mm, ip);
-	if (vma && vma->vm_file) {
-		struct file *f = vma->vm_file;
-		char *buf = (char *)__get_free_page(GFP_NOWAIT);
-		if (buf) {
-			char *p;
-
-			p = file_path(f, buf, PAGE_SIZE);
-			if (IS_ERR(p))
-				p = "?";
-			printk("%s%s[%lx+%lx]", prefix, kbasename(p),
-					vma->vm_start,
-					vma->vm_end - vma->vm_start);
-			free_page((unsigned long)buf);
-		}
-	}
-	up_read(&mm->mmap_sem);
-}
-
 #if defined(CONFIG_PROVE_LOCKING) || defined(CONFIG_DEBUG_ATOMIC_SLEEP)
 void __might_fault(const char *file, int line)
 {


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related

* Re: [PATCH 00/16] remove eight obsolete architectures
From: Christoph Hellwig @ 2018-03-15 14:17 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, linux-block, linux-fbdev, linux-watchdog,
	open list:DOCUMENTATION, Networking, dri-devel, linux-usb,
	linux-wireless, Linux Kernel Mailing List, linux-pwm, linux-spi,
	David Howells, IDE-ML, Hannes Reinecke, open list:HID CORE LAYER,
	Linux FS-devel Mailing List, Linux-MM, linux-rtc
In-Reply-To: <CAK8P3a01pfvsdM1mR8raU9dA7p4H-jRJz2Y8-+KEY76W_Mukpg@mail.gmail.com>

On Thu, Mar 15, 2018 at 11:42:25AM +0100, Arnd Bergmann wrote:
> Is anyone producing a chip that includes enough of the Privileged ISA spec
> to have things like system calls, but not the MMU parts?

Various SiFive SOCs seem to support M and U mode, but no S mode or
iommu.  That should be enough for nommu Linux running in M mode if
someone cares enough to actually port it.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH 11/16] treewide: simplify Kconfig dependencies for removed archs
From: Kalle Valo @ 2018-03-15 12:54 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-block-u79uwXL29TY76Z2rM5mHXA,
	linux-ide-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	linux-pwm-u79uwXL29TY76Z2rM5mHXA,
	linux-rtc-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg
In-Reply-To: <20180314144614.1632190-1-arnd-r2nGTMty4D4@public.gmane.org>

Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> writes:

> A lot of Kconfig symbols have architecture specific dependencies.
> In those cases that depend on architectures we have already removed,
> they can be omitted.
>
> Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>

[...]

>  drivers/net/wireless/cisco/Kconfig   |  2 +-

Acked-by: Kalle Valo <kvalo-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH 00/16] remove eight obsolete architectures
From: Arnd Bergmann @ 2018-03-15 10:42 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: linux-arch, linux-block, linux-fbdev, linux-watchdog,
	open list:DOCUMENTATION, Networking, linux-usb, linux-wireless,
	Linux Kernel Mailing List, linux-pwm, linux-spi, David Howells,
	IDE-ML, dri-devel, open list:HID CORE LAYER,
	Linux FS-devel Mailing List, Linux-MM, linux-rtc
In-Reply-To: <6c9d075c-d7a8-72a5-9b2d-af1feaa06c6c@suse.de>

On Thu, Mar 15, 2018 at 10:59 AM, Hannes Reinecke <hare@suse.de> wrote:
> On 03/15/2018 10:42 AM, David Howells wrote:
>> Do we have anything left that still implements NOMMU?
>>
> RISC-V ?
> (evil grin :-)

Is anyone producing a chip that includes enough of the Privileged ISA spec
to have things like system calls, but not the MMU parts?

I thought at least initially the kernel only supports hardware that has a rather
complete feature set.

       Arnd
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox