Re: [PATCH 05/10] hwmon: generic-pwm-tachometer: Add generic PWM based tachometer
On 21.02.2018 16:46, Guenter Roeck wrote: On 02/20/2018 11:15 PM, Mikko Perttunen wrote: AIUI, the PWM framework already exposes a sysfs node with period information. We should just use that instead of adding a new driver for this. I am kind of lost. Please explain. Are you saying that we should drop the pwm-fan driver as well (which goes the opposite way), as well as any other drivers doing anything with pwm signals, because after all those signals are already exposed to userspace a sysfs attributes, and a kernel driver to abstract those values is thus not needed ? The only thing this driver does is do a constant division in kernelspace. I'm not really seeing why that couldn't be done in userspace. But if you think it's appropriate to do the RPM conversion in kernelspace then I'm not greatly opposed to that. In any case, we cannot add something like this to device tree since it's not a hardware device. So you are saying there is no means to express in devicetree that a pwm input is connected to a fan ? How is that not hardware ? If so, how do you express in devicetree that a pwm signal is connected to anything ? If we want to describe that the tachometer is connected to a fan, then we should have a fan node in the board's device tree. We don't have a chip that has a thing called "generic-pwm-tachometer" attached to it. (We have chips that have a "nvidia,tegra186-tachometer", so it's proper to have that.) Thanks, Mikko Guenter Mikko On 21.02.2018 08:58, Rajkumar Rampelli wrote: Add generic PWM based tachometer driver via HWMON interface to report the RPM of motor. This drivers get the period/duty cycle from PWM IP which captures the motor PWM output. This driver implements a simple interface for monitoring the speed of a fan and exposes it in roatations per minute (RPM) to the user space by using the hwmon's sysfs interface Signed-off-by: Rajkumar Rampelli --- Documentation/hwmon/generic-pwm-tachometer | 17 + drivers/hwmon/Kconfig | 10 +++ drivers/hwmon/Makefile | 1 + drivers/hwmon/generic-pwm-tachometer.c | 112 + 4 files changed, 140 insertions(+) create mode 100644 Documentation/hwmon/generic-pwm-tachometer create mode 100644 drivers/hwmon/generic-pwm-tachometer.c diff --git a/Documentation/hwmon/generic-pwm-tachometer b/Documentation/hwmon/generic-pwm-tachometer new file mode 100644 index 000..e0713ee --- /dev/null +++ b/Documentation/hwmon/generic-pwm-tachometer @@ -0,0 +1,17 @@ +Kernel driver generic-pwm-tachometer + + +This driver enables the use of a PWM module to monitor a fan. It uses the +generic PWM interface and can be used on SoCs as along as the SoC supports +Tachometer controller that moniors the Fan speed in periods. + +Author: Rajkumar Rampelli + +Description +--- + +The driver implements a simple interface for monitoring the Fan speed using +PWM module and Tachometer controller. It requests period value through PWM +capture interface to Tachometer and measures the Rotations per minute using +received period value. It exposes the Fan speed in RPM to the user space by +using the hwmon's sysfs interface. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ef23553..8912dcb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1878,6 +1878,16 @@ config SENSORS_XGENE If you say yes here you get support for the temperature and power sensors for APM X-Gene SoC. +config GENERIC_PWM_TACHOMETER +tristate "Generic PWM based tachometer driver" +depends on PWM +help + Enables a driver to use PWM signal from motor to use + for measuring the motor speed. The RPM is captured by + PWM modules which has PWM capture capability and this + drivers reads the captured data from PWM IP to convert + it to speed in RPM. + if ACPI comment "ACPI drivers" diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index f814b4a..9dcc374 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -175,6 +175,7 @@ obj-$(CONFIG_SENSORS_WM8350)+= wm8350-hwmon.o obj-$(CONFIG_SENSORS_XGENE)+= xgene-hwmon.o obj-$(CONFIG_PMBUS)+= pmbus/ +obj-$(CONFIG_GENERIC_PWM_TACHOMETER) += generic-pwm-tachometer.o ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG diff --git a/drivers/hwmon/generic-pwm-tachometer.c b/drivers/hwmon/generic-pwm-tachometer.c new file mode 100644 index 000..9354d43 --- /dev/null +++ b/drivers/hwmon/generic-pwm-tachometer.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without ev
Re: [PATCH 1/4] drm/atomic: integrate modeset lock with private objects
On Wed, Feb 21, 2018 at 10:07 AM, Ville Syrjälä wrote: > On Wed, Feb 21, 2018 at 09:54:49AM -0500, Rob Clark wrote: >> On Wed, Feb 21, 2018 at 9:49 AM, Ville Syrjälä >> wrote: >> > On Wed, Feb 21, 2018 at 09:37:21AM -0500, Rob Clark wrote: >> >> Follow the same pattern of locking as with other state objects. This >> >> avoids boilerplate in the driver. >> > >> > I'm not sure we really want to do this. What if the driver wants a >> > custom locking scheme for this state? >> >> That seems like something we want to discourage, ie. all the more >> reason for this patch. >> >> There is no reason drivers could not split their global state into >> multiple private objs's, each with their own lock, for more fine >> grained locking. That is basically the only valid reason I can think >> of for "custom locking". > > In i915 we have at least one case that would want something close to an > rwlock. Any crtc lock is enough for read, need all of them for write. > Though if we wanted to use private objs for that we might need to > actually make the states refcounted as well, otherwise I can imagine > we might land in some use-after-free issues once again. > > Maybe we could duplicate the state into per-crtc and global copies, but > then we have to keep all of those in sync somehow which doesn't sound > particularly pleasant. Or just keep your own driver lock for read, and use that plus the core modeset lock for write? BR, -R > >> >> (And ofc drivers could add there own locks in addition to what is done >> by core, but I'd rather look at that on a case by case basis, rather >> than it being part of the boilerplate in each driver.) >> >> BR, >> -R >> >> >> >> >> Signed-off-by: Rob Clark >> >> --- >> >> drivers/gpu/drm/drm_atomic.c | 9 - >> >> include/drm/drm_atomic.h | 5 + >> >> 2 files changed, 13 insertions(+), 1 deletion(-) >> >> >> >> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c >> >> index fc8c4da409ff..004e621ab307 100644 >> >> --- a/drivers/gpu/drm/drm_atomic.c >> >> +++ b/drivers/gpu/drm/drm_atomic.c >> >> @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj >> >> *obj, >> >> { >> >> memset(obj, 0, sizeof(*obj)); >> >> >> >> + drm_modeset_lock_init(&obj->lock); >> >> + >> >> obj->state = state; >> >> obj->funcs = funcs; >> >> } >> >> @@ -1093,6 +1095,7 @@ void >> >> drm_atomic_private_obj_fini(struct drm_private_obj *obj) >> >> { >> >> obj->funcs->atomic_destroy_state(obj, obj->state); >> >> + drm_modeset_lock_fini(&obj->lock); >> >> } >> >> EXPORT_SYMBOL(drm_atomic_private_obj_fini); >> >> >> >> @@ -1113,7 +1116,7 @@ struct drm_private_state * >> >> drm_atomic_get_private_obj_state(struct drm_atomic_state *state, >> >>struct drm_private_obj *obj) >> >> { >> >> - int index, num_objs, i; >> >> + int index, num_objs, i, ret; >> >> size_t size; >> >> struct __drm_private_objs_state *arr; >> >> struct drm_private_state *obj_state; >> >> @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct >> >> drm_atomic_state *state, >> >> if (obj == state->private_objs[i].ptr) >> >> return state->private_objs[i].state; >> >> >> >> + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); >> >> + if (ret) >> >> + return ERR_PTR(ret); >> >> + >> >> num_objs = state->num_private_objs + 1; >> >> size = sizeof(*state->private_objs) * num_objs; >> >> arr = krealloc(state->private_objs, size, GFP_KERNEL); >> >> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h >> >> index 09076a625637..9ae53b73c9d2 100644 >> >> --- a/include/drm/drm_atomic.h >> >> +++ b/include/drm/drm_atomic.h >> >> @@ -218,6 +218,11 @@ struct drm_private_state_funcs { >> >> * &drm_modeset_lock is required to duplicate and update this object's >> >> state. >> >> */ >> >> struct drm_private_obj { >> >> + /** >> >> + * @lock: Modeset lock to protect the state object. >> >> + */ >> >> + struct drm_modeset_lock lock; >> >> + >> >> /** >> >>* @state: Current atomic state for this driver private object. >> >>*/ >> >> -- >> >> 2.14.3 >> >> >> >> ___ >> >> dri-devel mailing list >> >> dri-de...@lists.freedesktop.org >> >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > >> > -- >> > Ville Syrjälä >> > Intel OTC > > -- > Ville Syrjälä > Intel OTC
Re: [PATCH 1/4] drm/atomic: integrate modeset lock with private objects
Hey, Op 21-02-18 om 15:37 schreef Rob Clark: > Follow the same pattern of locking as with other state objects. This > avoids boilerplate in the driver. I'm afraid this will prohibit any uses of this on i915, since it still uses legacy lock_all(). Oh well, afaict nothing in i915 uses private objects, so I don't think it's harmful. :) Could you cc intel-gfx just in case? > Signed-off-by: Rob Clark > --- > drivers/gpu/drm/drm_atomic.c | 9 - > include/drm/drm_atomic.h | 5 + > 2 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index fc8c4da409ff..004e621ab307 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj *obj, > { > memset(obj, 0, sizeof(*obj)); > > + drm_modeset_lock_init(&obj->lock); > + > obj->state = state; > obj->funcs = funcs; > } > @@ -1093,6 +1095,7 @@ void > drm_atomic_private_obj_fini(struct drm_private_obj *obj) > { > obj->funcs->atomic_destroy_state(obj, obj->state); > + drm_modeset_lock_fini(&obj->lock); > } > EXPORT_SYMBOL(drm_atomic_private_obj_fini); > > @@ -1113,7 +1116,7 @@ struct drm_private_state * > drm_atomic_get_private_obj_state(struct drm_atomic_state *state, >struct drm_private_obj *obj) > { > - int index, num_objs, i; > + int index, num_objs, i, ret; > size_t size; > struct __drm_private_objs_state *arr; > struct drm_private_state *obj_state; > @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct > drm_atomic_state *state, > if (obj == state->private_objs[i].ptr) > return state->private_objs[i].state; > > + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); > + if (ret) > + return ERR_PTR(ret); > + > num_objs = state->num_private_objs + 1; > size = sizeof(*state->private_objs) * num_objs; > arr = krealloc(state->private_objs, size, GFP_KERNEL); > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h > index 09076a625637..9ae53b73c9d2 100644 > --- a/include/drm/drm_atomic.h > +++ b/include/drm/drm_atomic.h > @@ -218,6 +218,11 @@ struct drm_private_state_funcs { > * &drm_modeset_lock is required to duplicate and update this object's state. > */ > struct drm_private_obj { > + /** > + * @lock: Modeset lock to protect the state object. > + */ > + struct drm_modeset_lock lock; > + > /** >* @state: Current atomic state for this driver private object. >*/
回覆: [PATCH v3] Handle vendor defined behavior in tcpci_init, tcpci_set_vconn and export tcpci_irq. More operations can be extended in tcpci_data if needed. According to TCPCI specification, 4.4.5.2 RO
Hi Gerg, Thank you! I've fixed it and sent another email. Best Regards, * Shu-Fan Lee Richtek Technology Corporation TEL: +886-3-5526789 #2359 FAX: +886-3-5526612 * 寄件者: Greg KH 寄件日期: 2018年2月21日 下午 10:39 收件者: ShuFanLee 副本: heikki.kroge...@linux.intel.com; li...@roeck-us.net; shufan_lee(李書帆); cy_huang(黃啟原); linux-kernel@vger.kernel.org; linux-...@vger.kernel.org 主旨: Re: [PATCH v3] Handle vendor defined behavior in tcpci_init, tcpci_set_vconn and export tcpci_irq. More operations can be extended in tcpci_data if needed. According to TCPCI specification, 4.4.5.2 ROLE_CONTROL, TCPC shall not start DRP toggling until ... On Wed, Feb 21, 2018 at 10:30:34PM +0800, ShuFanLee wrote: > From: ShuFanLee > > Signed-off-by: ShuFanLee Something went really wrong with your subject line :( Please fix and try again. thanks, greg k-h * Email Confidentiality Notice The information contained in this e-mail message (including any attachments) may be confidential, proprietary, privileged, or otherwise exempt from disclosure under applicable laws. It is intended to be conveyed only to the designated recipient(s). Any use, dissemination, distribution, printing, retaining or copying of this e-mail (including its attachments) by unintended recipient(s) is strictly prohibited and may be unlawful. If you are not an intended recipient of this e-mail, or believe that you have received this e-mail in error, please notify the sender immediately (by replying to this e-mail), delete any and all copies of this e-mail (including any attachments) from your system, and do not disclose the content of this e-mail to any other person. Thank you!
Re: [PATCH v9 07/11] media: i2c: ov772x: Support frame interval handling
Hi Hans, On Wed, Feb 21, 2018 at 01:12:14PM +0100, Hans Verkuil wrote: [snip] > > +static int ov772x_g_frame_interval(struct v4l2_subdev *sd, > > + struct v4l2_subdev_frame_interval *ival) > > +{ > > + struct ov772x_priv *priv = to_ov772x(sd); > > + struct v4l2_fract *tpf = &ival->interval; > > + > > + memset(ival->reserved, 0, sizeof(ival->reserved)); > > This memset... > > > + tpf->numerator = 1; > > + tpf->denominator = priv->fps; > > + > > + return 0; > > +} > > + > > +static int ov772x_s_frame_interval(struct v4l2_subdev *sd, > > + struct v4l2_subdev_frame_interval *ival) > > +{ > > + struct ov772x_priv *priv = to_ov772x(sd); > > + struct v4l2_fract *tpf = &ival->interval; > > + > > + memset(ival->reserved, 0, sizeof(ival->reserved)); > > ... and this memset can be dropped. The core code will memset this for you. > > I see! Ok, I'll drop them in v10 > > + > > + return ov772x_set_frame_rate(priv, tpf, priv->cfmt, priv->win); > > +} > > + > > static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl) > > { > > struct ov772x_priv *priv = container_of(ctrl->handler, > > @@ -757,6 +905,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, > > const struct ov772x_win_size *win) > > { > > struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev); > > + struct v4l2_fract tpf; > > int ret; > > u8 val; > > > > @@ -885,6 +1034,13 @@ static int ov772x_set_params(struct ov772x_priv *priv, > > if (ret < 0) > > goto ov772x_set_fmt_error; > > > > + /* COM4, CLKRC: Set pixel clock and framerate. */ > > + tpf.numerator = 1; > > + tpf.denominator = priv->fps; > > + ret = ov772x_set_frame_rate(priv, &tpf, cfmt, win); > > + if (ret < 0) > > + goto ov772x_set_fmt_error; > > + > > /* > > * set COM8 > > */ > > @@ -1043,6 +1199,24 @@ static const struct v4l2_subdev_core_ops > > ov772x_subdev_core_ops = { > > .s_power= ov772x_s_power, > > }; > > > > +static int ov772x_enum_frame_interval(struct v4l2_subdev *sd, > > + struct v4l2_subdev_pad_config *cfg, > > + struct v4l2_subdev_frame_interval_enum > > *fie) > > +{ > > + if (fie->pad || fie->index >= OV772X_N_FRAME_INTERVALS) > > + return -EINVAL; > > + > > + if (fie->width != VGA_WIDTH && fie->width != QVGA_WIDTH) > > + return -EINVAL; > > + if (fie->height != VGA_HEIGHT && fie->height != QVGA_HEIGHT) > > + return -EINVAL; > > + > > + fie->interval.numerator = 1; > > + fie->interval.denominator = ov772x_frame_intervals[fie->index]; > > + > > + return 0; > > +} > > + > > static int ov772x_enum_mbus_code(struct v4l2_subdev *sd, > > struct v4l2_subdev_pad_config *cfg, > > struct v4l2_subdev_mbus_code_enum *code) > > @@ -1055,14 +1229,17 @@ static int ov772x_enum_mbus_code(struct v4l2_subdev > > *sd, > > } > > > > static const struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { > > - .s_stream = ov772x_s_stream, > > + .s_stream = ov772x_s_stream, > > + .s_frame_interval = ov772x_s_frame_interval, > > + .g_frame_interval = ov772x_g_frame_interval, > > }; > > > > static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { > > - .enum_mbus_code = ov772x_enum_mbus_code, > > - .get_selection = ov772x_get_selection, > > - .get_fmt= ov772x_get_fmt, > > - .set_fmt= ov772x_set_fmt, > > + .enum_frame_interval= ov772x_enum_frame_interval, > > + .enum_mbus_code = ov772x_enum_mbus_code, > > + .get_selection = ov772x_get_selection, > > + .get_fmt= ov772x_get_fmt, > > + .set_fmt= ov772x_set_fmt, > > Shouldn't these last four ops be added in the previous patch? > They don't have anything to do with the frame interval support. > If you look closely you'll notice I have just re-aligned them, since I was at there to add enum_frame_interval operation > Anyway, after taking care of the memsets and these four ops you can add > my: > > Acked-by: Hans Verkuil Thanks j
Re: [PATCH 3/3] platform/chrome: mfd/cros_ec_dev: Add sysfs entry to set keyboard wake lid angle
On Wed, Feb 21, 2018 at 4:50 PM, Enric Balletbo i Serra wrote: > From: Gwendal Grignou > > This adds a sysfs attribute (/sys/class/chromeos/cros_ec/kb_wake_angle) > used to set and get the keyboard wake lid angle. This attribute is > present only if 2 accelerometers are controlled by the EC. > > This patch also moves the cros_ec features check before the device is > added so the features map obtained from the EC is ready on time. > +/* Keyboard wake angle control */ > +static ssize_t show_kb_wake_angle(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct ec_response_motion_sense *resp; > + struct ec_params_motion_sense *param; > + struct cros_ec_command *msg; > + int ret; > + struct cros_ec_dev *ec = container_of( > + dev, struct cros_ec_dev, class_dev); First of all, do not split lines like this. Second, consider just to add a preparatory patch which introduces #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) and use it here. > + > + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + param = (struct ec_params_motion_sense *)msg->data; > + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; > + msg->version = 2; > + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; > + param->kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE; > + msg->outsize = sizeof(*param); > + msg->insize = sizeof(*resp); > + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); > + if (ret < 0) > + goto exit; > + resp = (struct ec_response_motion_sense *)msg->data; > + ret = scnprintf(buf, PAGE_SIZE, "%d\n", > + resp->kb_wake_angle.ret); Looks like one line. > +exit: > + kfree(msg); > + return ret; > +} > + > +static ssize_t store_kb_wake_angle(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct ec_params_motion_sense *param; > + struct cros_ec_command *msg; > + int ret; > + struct cros_ec_dev *ec = container_of( > + dev, struct cros_ec_dev, class_dev); > + u16 angle; > + > + ret = kstrtou16(buf, 0, &angle); > + if (ret) > + return ret; > + > + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); > + if (!msg) > + return -ENOMEM; > + > + param = (struct ec_params_motion_sense *)msg->data; > + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; > + msg->version = 2; > + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; > + param->kb_wake_angle.data = angle; > + msg->outsize = sizeof(*param); > + msg->insize = sizeof(struct ec_response_motion_sense); > + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); > + kfree(msg); > + if (ret < 0) > + return ret; > + return count; > +} > + > /* Module initialization */ > > static DEVICE_ATTR(reboot, S_IWUSR | S_IRUGO, show_ec_reboot, > store_ec_reboot); > static DEVICE_ATTR(version, S_IRUGO, show_ec_version, NULL); > static DEVICE_ATTR(flashinfo, S_IRUGO, show_ec_flashinfo, NULL); > +static DEVICE_ATTR(kb_wake_angle, S_IWUSR | S_IRUGO, show_kb_wake_angle, > + store_kb_wake_angle); Consider to switch to DEVICE_ATTR_RO() DEVICE_ATTR_RW() -- With Best Regards, Andy Shevchenko
Re: [PATCH 1/7] ARM: disallow combining XIP and LTO
On Wed, 21 Feb 2018, Arnd Bergmann wrote: > On Wed, Feb 21, 2018 at 4:01 AM, Nicolas Pitre > wrote: > > On Tue, 20 Feb 2018, Arnd Bergmann wrote: > > > >> This fails during deflate_xip_data.sh > >> > >> /home/arnd/cross-gcc/bin/arm-linux-gnueabi-objcopy -O binary -R .comment > >> -S vmlinux arch/arm/boot/xipImage && /bin/bash -c > >> '/git/arm-soc/arch/arm/boot/deflate_xip_data.sh vmlinux > >> arch/arm/boot/xipImage || { rm -f arch/arm/boot/xipImage; false; }' > >> make -f /git/arm-soc/scripts/Makefile.modpost > >> + sym_val __data_loc > >> + sed -n / __data_loc$/{s/ .*$//p;q} > >> + /home/arnd/cross-gcc/bin/arm-linux-gnueabi-gcc-nm vmlinux > >> /home/arnd/cross-gcc/lib/gcc/arm-linux-gnueabi/8.0.1/../../../../arm-linux-gnueabi/bin/nm > >> terminated with signal 13 [Broken pipe] > >> + local val=ac74c0f4 > >> + [ ac74c0f4 ] > >> + echo 2893332724 > >> + __data_loc=2893332724 > >> + sym_val _edata_loc > >> + /home/arnd/cross-gcc/bin/arm-linux-gnueabi-gcc-nm vmlinux > >> + sed -n / _edata_loc$/{s/ .*$//p;q} > >> /home/arnd/cross-gcc/lib/gcc/arm-linux-gnueabi/8.0.1/../../../../arm-linux-gnueabi/bin/nm > >> terminated with signal 13 [Broken pipe] > >> + local val=ac7b8744 > >> + [ ac7b8744 ] > >> + echo 2893776708 > >> + _edata_loc=2893776708 > >> + sym_val _xiprom > >> + sed -n / _xiprom$/{s/ .*$//p;q} > >> + /home/arnd/cross-gcc/bin/arm-linux-gnueabi-gcc-nm vmlinux > >> /home/arnd/cross-gcc/lib/gcc/arm-linux-gnueabi/8.0.1/../../../../arm-linux-gnueabi/bin/nm > >> terminated with signal 13 [Broken pipe] > >> > >> Obviously we want to make the combination work, no idea why it doesn't. > >> > > > > You should move this to config XIP_DEFLATED_DATA instead. > > Right, makes sense. I'd still prever nm to not crash, but that would be a > small > improvement. I'll have a look at nm. However this feature is linked to head-inflate-data.c (your patch #5/7) and I have no obvious quick solution in mind for that one. Nicolas
[PATCH v3 6/6] platform/x86: topstar-laptop: update copyright and fix some comments
Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/topstar-laptop.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index bf9761092c7e..294729c98267 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -1,10 +1,11 @@ /* - * ACPI driver for Topstar notebooks (hotkeys support only) + * Topstar Laptop ACPI Extras driver * * Copyright (c) 2009 Herton Ronaldo Krzesinski + * Copyright (c) 2018 Guillaume Douézan-Grard * * Implementation inspired by existing x86 platform drivers, in special - * asus/eepc/fujitsu-laptop, thanks to their authors + * asus/eepc/fujitsu-laptop, thanks to their authors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -397,5 +398,6 @@ module_init(topstar_laptop_init); module_exit(topstar_laptop_exit); MODULE_AUTHOR("Herton Ronaldo Krzesinski"); +MODULE_AUTHOR("Guillaume Douézan-Grard"); MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); MODULE_LICENSE("GPL"); -- 2.16.1
[PATCH v3 4/6] platform/x86: topstar-laptop: add platform device
* add a platform device to support further addition of a led subsystem, * register the existing input device to this platform device Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/topstar-laptop.c | 59 +-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index fbf020e8a0e1..792c90d62724 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -20,11 +20,13 @@ #include #include #include +#include #define TOPSTAR_LAPTOP_CLASS "topstar" struct topstar_laptop { struct acpi_device *device; + struct platform_device *platform; struct input_dev *input; }; @@ -80,6 +82,7 @@ static int topstar_input_init(struct topstar_laptop *topstar) input->name = "Topstar Laptop extra buttons"; input->phys = TOPSTAR_LAPTOP_CLASS "/input0"; input->id.bustype = BUS_HOST; + input->dev.parent = &topstar->platform->dev; err = sparse_keymap_setup(input, topstar_keymap, NULL); if (err) { @@ -106,6 +109,42 @@ static void topstar_input_exit(struct topstar_laptop *topstar) input_unregister_device(topstar->input); } +/* + * Platform + */ + +static struct platform_driver topstar_platform_driver = { + .driver = { + .name = TOPSTAR_LAPTOP_CLASS, + }, +}; + +static int topstar_platform_init(struct topstar_laptop *topstar) +{ + int err; + + topstar->platform = platform_device_alloc(TOPSTAR_LAPTOP_CLASS, -1); + if (!topstar->platform) + return -ENOMEM; + + platform_set_drvdata(topstar->platform, topstar); + + err = platform_device_add(topstar->platform); + if (err) + goto err_device_put; + + return 0; + +err_device_put: + platform_device_put(topstar->platform); + return err; +} + +static void topstar_platform_exit(struct topstar_laptop *topstar) +{ + platform_device_unregister(topstar->platform); +} + /* * ACPI */ @@ -171,12 +210,18 @@ static int topstar_acpi_add(struct acpi_device *device) if (err) goto err_free; - err = topstar_input_init(topstar); + err = topstar_platform_init(topstar); if (err) goto err_acpi_exit; + err = topstar_input_init(topstar); + if (err) + goto err_platform_exit; + return 0; +err_platform_exit: + topstar_platform_exit(topstar); err_acpi_exit: topstar_acpi_exit(topstar); err_free: @@ -189,6 +234,7 @@ static int topstar_acpi_remove(struct acpi_device *device) struct topstar_laptop *topstar = acpi_driver_data(device); topstar_input_exit(topstar); + topstar_platform_exit(topstar); topstar_acpi_exit(topstar); kfree(topstar); @@ -217,17 +263,26 @@ static int __init topstar_laptop_init(void) { int ret; - ret = acpi_bus_register_driver(&topstar_acpi_driver); + ret = platform_driver_register(&topstar_platform_driver); if (ret < 0) return ret; + ret = acpi_bus_register_driver(&topstar_acpi_driver); + if (ret < 0) + goto err_driver_unreg; + pr_info("ACPI extras driver loaded\n"); return 0; + +err_driver_unreg: + platform_driver_unregister(&topstar_platform_driver); + return ret; } static void __exit topstar_laptop_exit(void) { acpi_bus_unregister_driver(&topstar_acpi_driver); + platform_driver_unregister(&topstar_platform_driver); } module_init(topstar_laptop_init); -- 2.16.1
[PATCH v3 5/6] platform/x86: topstar-laptop: add Topstar U931/RVP7 WLAN LED workaround
Topstar U931 laptops provide a LED synced with the WLAN adapter hard-blocking state. Unfortunately, some models seem to be defective, making impossible to hard-block the adapter with the WLAN switch and thus the LED is useless. An ACPI method is available to programmatically control this switch and it indirectly allows to control the LED. This commit registers the LED within the corresponding subsystem, making possible for instance to use an rfkill-based trigger to synchronize the LED with the device state. This workaround is enabled automatically for Topstar U931/RVP7 laptops based on a DMI check. Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/Kconfig | 2 + drivers/platform/x86/topstar-laptop.c | 108 ++ 2 files changed, 110 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 9a8f96465cdc..bc66a31757db 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -742,6 +742,8 @@ config TOPSTAR_LAPTOP depends on ACPI depends on INPUT select INPUT_SPARSEKMAP + select LEDS_CLASS + select NEW_LEDS ---help--- This driver adds support for hotkeys found on Topstar laptops. diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 792c90d62724..bf9761092c7e 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -18,8 +18,10 @@ #include #include #include +#include #include #include +#include #include #define TOPSTAR_LAPTOP_CLASS "topstar" @@ -28,8 +30,77 @@ struct topstar_laptop { struct acpi_device *device; struct platform_device *platform; struct input_dev *input; + struct led_classdev led; }; +/* + * LED + */ + +static enum led_brightness topstar_led_get(struct led_classdev *led) +{ + return led->brightness; +} + +static int topstar_led_set(struct led_classdev *led, + enum led_brightness state) +{ + struct topstar_laptop *topstar = container_of(led, + struct topstar_laptop, led); + + struct acpi_object_list params; + union acpi_object in_obj; + unsigned long long int ret; + acpi_status status; + + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = 0x83; + + /* +* Topstar ACPI returns 0x30001 when the LED is ON and 0x3 when it +* is OFF. +*/ + status = acpi_evaluate_integer(topstar->device->handle, + "GETX", ¶ms, &ret); + if (ACPI_FAILURE(status)) + return -1; + + /* +* FNCX(0x83) toggles the LED (more precisely, it is supposed to +* act as an hardware switch and disconnect the WLAN adapter but +* it seems to be faulty on some models like the Topstar U931 +* Notebook). +*/ + if ((ret == 0x30001 && state == LED_OFF) + || (ret == 0x3 && state != LED_OFF)) { + status = acpi_execute_simple_method(topstar->device->handle, + "FNCX", 0x83); + if (ACPI_FAILURE(status)) + return -1; + } + + return 0; +} + +static int topstar_led_init(struct topstar_laptop *topstar) +{ + topstar->led = (struct led_classdev) { + .default_trigger = "rfkill0", + .brightness_get = topstar_led_get, + .brightness_set_blocking = topstar_led_set, + .name = TOPSTAR_LAPTOP_CLASS "::wlan", + }; + + return led_classdev_register(&topstar->platform->dev, &topstar->led); +} + +static void topstar_led_exit(struct topstar_laptop *topstar) +{ + led_classdev_unregister(&topstar->led); +} + /* * Input */ @@ -192,11 +263,37 @@ static void topstar_acpi_exit(struct topstar_laptop *topstar) topstar_acpi_fncx_switch(topstar->device, false); } +/* + * Enable software-based WLAN LED control on systems with defective + * hardware switch. + */ +static bool led_workaround; + +static int dmi_led_workaround(const struct dmi_system_id *id) +{ + led_workaround = true; + return 0; +} + +static const struct dmi_system_id topstar_dmi_ids[] = { + { + .callback = dmi_led_workaround, + .ident = "Topstar U931/RVP7", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "U931"), + DMI_MATCH(DMI_BOARD_VERSION, "RVP7"), + }, + }, + {} +}; + static int topstar_acpi_add(struct acpi_device *device) { struct topstar_laptop *topstar; int err; + dmi_check_system(topstar_dmi_ids); + topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL); if (!topstar) return -ENOMEM; @@ -218,8 +315,16 @@ static int topstar_a
[PATCH v3 3/6] platform/x86: topstar-laptop: split ACPI events and input handling
* get the `acpi_device` from the `topstar_laptop` struct, * split input registering and `sparse_keymap` events from ACPI events handling, * use notify, init and exit functions for ACPI and input handling Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/topstar-laptop.c | 109 ++ 1 file changed, 71 insertions(+), 38 deletions(-) diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 17f22a085d9a..fbf020e8a0e1 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -24,9 +24,14 @@ #define TOPSTAR_LAPTOP_CLASS "topstar" struct topstar_laptop { + struct acpi_device *device; struct input_dev *input; }; +/* + * Input + */ + static const struct key_entry topstar_keymap[] = { { KE_KEY, 0x80, { KEY_BRIGHTNESSUP } }, { KE_KEY, 0x81, { KEY_BRIGHTNESSDOWN } }, @@ -57,40 +62,12 @@ static const struct key_entry topstar_keymap[] = { { KE_END, 0 } }; -static void topstar_acpi_notify(struct acpi_device *device, u32 event) +static void topstar_input_notify(struct topstar_laptop *topstar, int event) { - static bool dup_evnt[2]; - bool *dup; - struct topstar_laptop *topstar = acpi_driver_data(device); - - /* 0x83 and 0x84 key events comes duplicated... */ - if (event == 0x83 || event == 0x84) { - dup = &dup_evnt[event - 0x83]; - if (*dup) { - *dup = false; - return; - } - *dup = true; - } - if (!sparse_keymap_report_event(topstar->input, event, 1, true)) pr_info("unknown event = 0x%02x\n", event); } -static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state) -{ - acpi_status status; - - status = acpi_execute_simple_method(device->handle, "FNCX", - state ? 0x86 : 0x87); - if (ACPI_FAILURE(status)) { - pr_err("Unable to switch FNCX notifications\n"); - return -ENODEV; - } - - return 0; -} - static int topstar_input_init(struct topstar_laptop *topstar) { struct input_dev *input; @@ -124,9 +101,62 @@ static int topstar_input_init(struct topstar_laptop *topstar) return err; } +static void topstar_input_exit(struct topstar_laptop *topstar) +{ + input_unregister_device(topstar->input); +} + +/* + * ACPI + */ + +static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state) +{ + acpi_status status; + u64 arg = state ? 0x86 : 0x87; + + status = acpi_execute_simple_method(device->handle, "FNCX", arg); + if (ACPI_FAILURE(status)) { + pr_err("Unable to switch FNCX notifications\n"); + return -ENODEV; + } + + return 0; +} + +static void topstar_acpi_notify(struct acpi_device *device, u32 event) +{ + struct topstar_laptop *topstar = acpi_driver_data(device); + static bool dup_evnt[2]; + bool *dup; + + /* 0x83 and 0x84 key events comes duplicated... */ + if (event == 0x83 || event == 0x84) { + dup = &dup_evnt[event - 0x83]; + if (*dup) { + *dup = false; + return; + } + *dup = true; + } + + topstar_input_notify(topstar, event); +} + +static int topstar_acpi_init(struct topstar_laptop *topstar) +{ + return topstar_acpi_fncx_switch(topstar->device, true); +} + +static void topstar_acpi_exit(struct topstar_laptop *topstar) +{ + topstar_acpi_fncx_switch(topstar->device, false); +} + static int topstar_acpi_add(struct acpi_device *device) { struct topstar_laptop *topstar; + int err; topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL); if (!topstar) @@ -134,30 +164,34 @@ static int topstar_acpi_add(struct acpi_device *device) strcpy(acpi_device_name(device), "Topstar TPSACPI"); strcpy(acpi_device_class(device), TOPSTAR_LAPTOP_CLASS); + device->driver_data = topstar; + topstar->device = device; - if (topstar_acpi_fncx_switch(device, true)) + err = topstar_acpi_init(topstar); + if (err) goto err_free; - if (topstar_input_init(topstar)) - goto err_free; + err = topstar_input_init(topstar); + if (err) + goto err_acpi_exit; - device->driver_data = topstar; return 0; +err_acpi_exit: + topstar_acpi_exit(topstar); err_free: kfree(topstar); - return -ENODEV; + return err; } static int topstar_acpi_remove(struct acpi_device *device) { struct topstar_laptop *topstar = acpi_driver_data(device); - topstar_acpi_fncx_switch(device, false); + topstar_input_exit(topstar); + topstar_acpi_exit(topstar); - input
Re: [PATCH 2/2] ARM: pinctrl: stm32: Optimizes and enhances stm32gpio irqchip
Maybe you could remove ARM from commit header. On 02/21/2018 02:50 PM, Radoslaw Pietrzyk wrote: - removes unneeded irq_chip.irq_eoi callback - adds irq_chip.irq_set_wake callback for possible in the future GPIO wakeup Signed-off-by: Radoslaw Pietrzyk --- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 617df16..5b1740d 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -268,10 +268,10 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data) static struct irq_chip stm32_gpio_irq_chip = { .name = "stm32gpio", - .irq_eoi= irq_chip_eoi_parent, .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = irq_chip_set_wake_parent, .irq_request_resources = stm32_gpio_irq_request_resources, .irq_release_resources = stm32_gpio_irq_release_resources, };
[PATCH v3 2/6] platform/x86: topstar-laptop: use consistent naming scheme
* use module prefix naming scheme for functions and programming constructs, * consistent label names Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/topstar-laptop.c | 82 +-- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index b4807b868a69..17f22a085d9a 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -21,10 +21,10 @@ #include #include -#define ACPI_TOPSTAR_CLASS "topstar" +#define TOPSTAR_LAPTOP_CLASS "topstar" -struct topstar_hkey { - struct input_dev *inputdev; +struct topstar_laptop { + struct input_dev *input; }; static const struct key_entry topstar_keymap[] = { @@ -57,11 +57,11 @@ static const struct key_entry topstar_keymap[] = { { KE_END, 0 } }; -static void acpi_topstar_notify(struct acpi_device *device, u32 event) +static void topstar_acpi_notify(struct acpi_device *device, u32 event) { static bool dup_evnt[2]; bool *dup; - struct topstar_hkey *hkey = acpi_driver_data(device); + struct topstar_laptop *topstar = acpi_driver_data(device); /* 0x83 and 0x84 key events comes duplicated... */ if (event == 0x83 || event == 0x84) { @@ -73,11 +73,11 @@ static void acpi_topstar_notify(struct acpi_device *device, u32 event) *dup = true; } - if (!sparse_keymap_report_event(hkey->inputdev, event, 1, true)) + if (!sparse_keymap_report_event(topstar->input, event, 1, true)) pr_info("unknown event = 0x%02x\n", event); } -static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) +static int topstar_acpi_fncx_switch(struct acpi_device *device, bool state) { acpi_status status; @@ -91,72 +91,72 @@ static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) return 0; } -static int acpi_topstar_init_hkey(struct topstar_hkey *hkey) +static int topstar_input_init(struct topstar_laptop *topstar) { struct input_dev *input; - int error; + int err; input = input_allocate_device(); if (!input) return -ENOMEM; input->name = "Topstar Laptop extra buttons"; - input->phys = "topstar/input0"; + input->phys = TOPSTAR_LAPTOP_CLASS "/input0"; input->id.bustype = BUS_HOST; - error = sparse_keymap_setup(input, topstar_keymap, NULL); - if (error) { + err = sparse_keymap_setup(input, topstar_keymap, NULL); + if (err) { pr_err("Unable to setup input device keymap\n"); goto err_free_dev; } - error = input_register_device(input); - if (error) { + err = input_register_device(input); + if (err) { pr_err("Unable to register input device\n"); goto err_free_dev; } - hkey->inputdev = input; + topstar->input = input; return 0; - err_free_dev: +err_free_dev: input_free_device(input); - return error; + return err; } -static int acpi_topstar_add(struct acpi_device *device) +static int topstar_acpi_add(struct acpi_device *device) { - struct topstar_hkey *tps_hkey; + struct topstar_laptop *topstar; - tps_hkey = kzalloc(sizeof(struct topstar_hkey), GFP_KERNEL); - if (!tps_hkey) + topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL); + if (!topstar) return -ENOMEM; strcpy(acpi_device_name(device), "Topstar TPSACPI"); - strcpy(acpi_device_class(device), ACPI_TOPSTAR_CLASS); + strcpy(acpi_device_class(device), TOPSTAR_LAPTOP_CLASS); - if (acpi_topstar_fncx_switch(device, true)) - goto add_err; + if (topstar_acpi_fncx_switch(device, true)) + goto err_free; - if (acpi_topstar_init_hkey(tps_hkey)) - goto add_err; + if (topstar_input_init(topstar)) + goto err_free; - device->driver_data = tps_hkey; + device->driver_data = topstar; return 0; -add_err: - kfree(tps_hkey); +err_free: + kfree(topstar); return -ENODEV; } -static int acpi_topstar_remove(struct acpi_device *device) +static int topstar_acpi_remove(struct acpi_device *device) { - struct topstar_hkey *tps_hkey = acpi_driver_data(device); + struct topstar_laptop *topstar = acpi_driver_data(device); - acpi_topstar_fncx_switch(device, false); + topstar_acpi_fncx_switch(device, false); - input_unregister_device(tps_hkey->inputdev); - kfree(tps_hkey); + input_unregister_device(topstar->input); + kfree(topstar); return 0; } @@ -168,14 +168,14 @@ static const struct acpi_device_id topstar_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, topstar_device_ids); -static struct acpi_driver
[PATCH v3 1/6] revert "topstar-laptop: convert to module_acpi_driver()"
Revert commit 15165594da65 ("topstar-laptop: convert to module_acpi_driver()") to later add a platform device. Signed-off-by: Guillaume Douézan-Grard --- drivers/platform/x86/topstar-laptop.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 1032c00b907b..b4807b868a69 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -178,7 +178,27 @@ static struct acpi_driver acpi_topstar_driver = { .notify = acpi_topstar_notify, }, }; -module_acpi_driver(acpi_topstar_driver); + +static int __init topstar_laptop_init(void) +{ + int ret; + + ret = acpi_bus_register_driver(&acpi_topstar_driver); + if (ret < 0) + return ret; + + pr_info("ACPI extras driver loaded\n"); + + return 0; +} + +static void __exit topstar_laptop_exit(void) +{ + acpi_bus_unregister_driver(&acpi_topstar_driver); +} + +module_init(topstar_laptop_init); +module_exit(topstar_laptop_exit); MODULE_AUTHOR("Herton Ronaldo Krzesinski"); MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); -- 2.16.1
[PATCH v3 0/6] Topstar U931/RVP7 ACPI LED Workaround
Hi Andy, Thank you for your review. Changes since the previous submission are highlighted below. On Topstar U931/RVP7 Notebooks, an issue prevents the WLAN toggle key from being properly managed by the Embedded Controller and successfully disconnect the adapter. A specific ACPI method allows to toggle the WLAN LED state regardless. Based on a DMI check, the LED is registered within the corresponding subsystem, making possible to use a software-based trigger (rfkill for instance, to synchronize the LED with the network interface state). Thank you for your time, -- Guillaume Douézan-Grard Changes since v2: * revert an older conversion from a generic module to an acpi driver module instead of undoing it manually, * separate commits for the renaming and the spliting phases, * DMI-based check instead of a module parameter, * copyright and minor fixes put at the end. Changes since v1: * leave devices names unchanged for ABI compatibility, * fix label names, * separate module authors definition, * add commit description to Patch 3. Guillaume Douézan-Grard (6): revert "topstar-laptop: convert to module_acpi_driver()" platform/x86: topstar-laptop: use consistent naming scheme platform/x86: topstar-laptop: split ACPI events and input handling platform/x86: topstar-laptop: add platform device platform/x86: topstar-laptop: add Topstar U931/RVP7 WLAN LED workaround platform/x86: topstar-laptop: update copyright and fix some comments drivers/platform/x86/Kconfig | 2 + drivers/platform/x86/topstar-laptop.c | 358 +++--- 2 files changed, 290 insertions(+), 70 deletions(-) -- 2.16.1
Re: [PATCH] netlink: put module reference if dump start fails
On Wed, 2018-02-21 at 15:54 +0100, Jason A. Donenfeld wrote: > On Wed, Feb 21, 2018 at 6:47 AM, Eric Dumazet wrote: > > > This probably should be queued up for stable. > > > > When was the bug added ? This would help a lot stable teams ... > > This needs to be backported to 4.16-rc0+, 4.15+, 4.14+, 4.13.14+, and 4.9.63+. I guess I should have asked you to provide an appropriate Fixes: tag, clearly identifying the commit that added the bug. Fixes: 12-digit-sha1 ("patch title") Thanks.
Re: [PATCH 2/2] ARM: pinctrl: stm32: Optimizes and enhances stm32gpio irqchip
Hi Radoslaw, On 02/21/2018 02:50 PM, Radoslaw Pietrzyk wrote: - removes unneeded irq_chip.irq_eoi callback - adds irq_chip.irq_set_wake callback for possible in the future GPIO wakeup Signed-off-by: Radoslaw Pietrzyk --- drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 617df16..5b1740d 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -268,10 +268,10 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data) static struct irq_chip stm32_gpio_irq_chip = { .name = "stm32gpio", - .irq_eoi= irq_chip_eoi_parent, .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = irq_chip_set_wake_parent, Thanks, this one was in my backlog. Acked-by: Alexandre TORGUE .irq_request_resources = stm32_gpio_irq_request_resources, .irq_release_resources = stm32_gpio_irq_release_resources, };
Re: [PATCH] RDMA/core: reduce IB_POLL_BATCH constant
> On Feb 21, 2018, at 8:44 AM, Sagi Grimberg wrote: > > >>> On Tue, 2018-02-20 at 21:59 +0100, Arnd Bergmann wrote: /* # of WCs to poll for with a single call to ib_poll_cq */ -#define IB_POLL_BATCH 16 +#define IB_POLL_BATCH 8 >>> >>> The purpose of batch polling is to minimize contention on the cq spinlock. >>> Reducing the IB_POLL_BATCH constant may affect performance negatively. Has >>> the performance impact of this change been verified for all affected drivers >>> (ib_srp, ib_srpt, ib_iser, ib_isert, NVMeOF, NVMeOF target, SMB Direct, NFS >>> over RDMA, ...)? >> Only the users of the DIRECT polling method use an on-stack >> array of ib_wc's. This is only the SRP drivers. >> The other two modes have use of a dynamically allocated array >> of ib_wc's that hangs off the ib_cq. These shouldn't need any >> reduction in the size of this array, and they are the common >> case. >> IMO a better solution would be to change ib_process_cq_direct >> to use a smaller on-stack array, and leave IB_POLL_BATCH alone. > > The only reason why I added this array on-stack was to allow consumers > that did not use ib_alloc_cq api to call it, but that seems like a > wrong decision when thinking it over again (as probably these users > did not set the wr_cqe correctly). > > How about we make ib_process_cq_direct use the cq wc array and add > a WARN_ON statement (and fail it gracefully) if the caller used this > API without calling ib_alloc_cq? Agreed, I prefer that all three modes use dynamically allocated memory for that array. > -- > diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c > index bc79ca8215d7..cd3e9e124834 100644 > --- a/drivers/infiniband/core/cq.c > +++ b/drivers/infiniband/core/cq.c > @@ -25,10 +25,10 @@ > #define IB_POLL_FLAGS \ >(IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) > > -static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc > *poll_wc) > +static int __ib_process_cq(struct ib_cq *cq, int budget) > { >int i, n, completed = 0; > - struct ib_wc *wcs = poll_wc ? : cq->wc; > + struct ib_wc *wcs = cq->wc; > >/* > * budget might be (-1) if the caller does not > @@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, > struct ib_wc *poll_wc) > */ > int ib_process_cq_direct(struct ib_cq *cq, int budget) > { > - struct ib_wc wcs[IB_POLL_BATCH]; > - > - return __ib_process_cq(cq, budget, wcs); > + if (unlikely(WARN_ON_ONCE(!cq->wc))) > + return 0; > + return __ib_process_cq(cq, budget); > } > EXPORT_SYMBOL(ib_process_cq_direct); > > @@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget) >struct ib_cq *cq = container_of(iop, struct ib_cq, iop); >int completed; > > - completed = __ib_process_cq(cq, budget, NULL); > + completed = __ib_process_cq(cq, budget); >if (completed < budget) { >irq_poll_complete(&cq->iop); >if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) > @@ -108,7 +108,7 @@ static void ib_cq_poll_work(struct work_struct *work) >struct ib_cq *cq = container_of(work, struct ib_cq, work); >int completed; > > - completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL); > + completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE); >if (completed >= IB_POLL_BUDGET_WORKQUEUE || >ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) >queue_work(ib_comp_wq, &cq->work); > -- -- Chuck Lever
Re: [PATCH RFC tools/lkmm 09/12] tools/memory-model: Add required herd7 version to README file
On Tue, 20 Feb 2018, Paul E. McKenney wrote: > LKMM and the herd7 tool are co-evolving, and out-of-date herd7 tools > produce inaccurate results, often with no obvious error messages. This > commit therefore adds the required herd7 version to the LKMM README file. > > Longer term, it would be good if .cat files could specify the required > version in a manner allowing herd7 to produce clear diagnostics. > > Suggested-by: Akira Yokosawa > Signed-off-by: Paul E. McKenney > --- > tools/memory-model/README | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/tools/memory-model/README b/tools/memory-model/README > index 91414a49fac5..ea950c566ffd 100644 > --- a/tools/memory-model/README > +++ b/tools/memory-model/README > @@ -20,7 +20,8 @@ that litmus test to be exercised within the Linux kernel. > REQUIREMENTS > > > -The "herd7" and "klitmus7" tools must be downloaded separately: > +Version 7.48 of the "herd7" and "klitmus7" tools must be downloaded > +separately: > >https://github.com/herd/herdtools7 The text immediately below this mentions the Docker image and gentoo package. Aren't they both seriously out of date at this point? In which case, shouldn't we remove them from the README? Alan
[PATCH] usb: phy-generic: Use gpiod_set_value_cansleep
The nop_reset and shutdown methods are called in a context that can sleep, so use gpiod_set_value_cansleep instead of gpiod_set_value. If you've connected the reset line to a GPIO expander, you'd get a kernel "slowpath" warning with gpiod_set_value. Signed-off-by: Mike Looijmans --- drivers/usb/phy/phy-generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 74ba882..a53b89b 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -63,9 +63,9 @@ static void nop_reset(struct usb_phy_generic *nop) if (!nop->gpiod_reset) return; - gpiod_set_value(nop->gpiod_reset, 1); + gpiod_set_value_cansleep(nop->gpiod_reset, 1); usleep_range(1, 2); - gpiod_set_value(nop->gpiod_reset, 0); + gpiod_set_value_cansleep(nop->gpiod_reset, 0); } /* interface to regulator framework */ @@ -159,7 +159,7 @@ void usb_gen_phy_shutdown(struct usb_phy *phy) { struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); - gpiod_set_value(nop->gpiod_reset, 1); + gpiod_set_value_cansleep(nop->gpiod_reset, 1); if (!IS_ERR(nop->clk)) clk_disable_unprepare(nop->clk); -- 1.9.1
Re: [PATCH v3] arm64: Add support for new control bits CTR_EL0.DIC and CTR_EL0.IDC
On Wed, Feb 21, 2018 at 07:49:06AM -0600, Shanker Donthineni wrote: > The DCache clean & ICache invalidation requirements for instructions > to be data coherence are discoverable through new fields in CTR_EL0. > The following two control bits DIC and IDC were defined for this > purpose. No need to perform point of unification cache maintenance > operations from software on systems where CPU caches are transparent. > > This patch optimize the three functions __flush_cache_user_range(), > clean_dcache_area_pou() and invalidate_icache_range() if the hardware > reports CTR_EL0.IDC and/or CTR_EL0.IDC. Basically it skips the two > instructions 'DC CVAU' and 'IC IVAU', and the associated loop logic > in order to avoid the unnecessary overhead. > > CTR_EL0.DIC: Instruction cache invalidation requirements for > instruction to data coherence. The meaning of this bit[29]. > 0: Instruction cache invalidation to the point of unification > is required for instruction to data coherence. > 1: Instruction cache cleaning to the point of unification is > not required for instruction to data coherence. > > CTR_EL0.IDC: Data cache clean requirements for instruction to data > coherence. The meaning of this bit[28]. > 0: Data cache clean to the point of unification is required for > instruction to data coherence, unless CLIDR_EL1.LoC == 0b000 > or (CLIDR_EL1.LoUIS == 0b000 && CLIDR_EL1.LoUU == 0b000). > 1: Data cache clean to the point of unification is not required > for instruction to data coherence. > > Signed-off-by: Philip Elcan > Signed-off-by: Shanker Donthineni > --- > Changes since v2: > -Included barriers, DSB/ISB with DIC set, and DSB with IDC set. > -Single Kconfig option. > > Changes since v1: > -Reworded commit text. > -Used the alternatives framework as Catalin suggested. > -Rebased on top of https://patchwork.kernel.org/patch/10227927/ > > arch/arm64/Kconfig | 12 > arch/arm64/include/asm/cache.h | 5 + > arch/arm64/include/asm/cpucaps.h | 4 +++- > arch/arm64/kernel/cpufeature.c | 40 > ++-- > arch/arm64/mm/cache.S| 21 +++-- > 5 files changed, 73 insertions(+), 9 deletions(-) > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig > index f55fe5b..82b8053 100644 > --- a/arch/arm64/Kconfig > +++ b/arch/arm64/Kconfig > @@ -1095,6 +1095,18 @@ config ARM64_RAS_EXTN > and access the new registers if the system supports the extension. > Platform RAS features may additionally depend on firmware support. > > +config ARM64_SKIP_CACHE_POU > + bool "Enable support to skip cache POU operations" > + default y > + help > + Explicit point of unification cache operations can be eliminated > + in software if the hardware handles transparently. The new bits in > + CTR_EL0, CTR_EL0.DIC and CTR_EL0.IDC indicates the hardware > + capabilities of ICache and DCache POU requirements. > + > + Selecting this feature will allow the kernel to optimize the POU > + cache maintaince operations where it requires 'D{I}C C{I}VAU' > + > endmenu Is it worth having a config option for this at all? The savings from turning this off seem trivial. > > config ARM64_SVE > diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h > index ea9bb4e..e22178b 100644 > --- a/arch/arm64/include/asm/cache.h > +++ b/arch/arm64/include/asm/cache.h > @@ -20,8 +20,13 @@ > > #define CTR_L1IP_SHIFT 14 > #define CTR_L1IP_MASK3 > +#define CTR_DMLINE_SHIFT 16 > +#define CTR_ERG_SHIFT20 > #define CTR_CWG_SHIFT24 > #define CTR_CWG_MASK 15 > +#define CTR_IDC_SHIFT28 > +#define CTR_DIC_SHIFT29 > +#define CTR_B31_SHIFT31 > > #define CTR_L1IP(ctr)(((ctr) >> CTR_L1IP_SHIFT) & > CTR_L1IP_MASK) > > diff --git a/arch/arm64/include/asm/cpucaps.h > b/arch/arm64/include/asm/cpucaps.h > index bb26382..8dd42ae 100644 > --- a/arch/arm64/include/asm/cpucaps.h > +++ b/arch/arm64/include/asm/cpucaps.h > @@ -45,7 +45,9 @@ > #define ARM64_HARDEN_BRANCH_PREDICTOR24 > #define ARM64_HARDEN_BP_POST_GUEST_EXIT 25 > #define ARM64_HAS_RAS_EXTN 26 > +#define ARM64_HAS_CACHE_IDC 27 > +#define ARM64_HAS_CACHE_DIC 28 > > -#define ARM64_NCAPS 27 > +#define ARM64_NCAPS 29 > > #endif /* __ASM_CPUCAPS_H */ > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index ff8a6e9..12e100a 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -199,12 +199,12 @@ static int __init register_cpu_hwcaps_dumper(void) > }; > > static const struct arm64_ftr_bits ftr_ctr[] = { > - ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FT
Re: [PATCH RFC tools/lkmm 10/12] tools/memory-model: Add a S lock-based external-view litmus test
On Tue, 20 Feb 2018, Paul E. McKenney wrote: > From: Alan Stern > > This commit adds a litmus test in which P0() and P1() form a lock-based S > litmus test, with the addition of P2(), which observes P0()'s and P1()'s Why do you call this an "S" litmus test? Isn't ISA2 a better description? > accesses with a full memory barrier but without the lock. This litmus > test asks whether writes carried out by two different processes under the > same lock will be seen in order by a third process not holding that lock. > The answer to this question is "yes" for all architectures supporting > the Linux kernel, but is "no" according to the current version of LKMM. > > A patch to LKMM is under development. > > Signed-off-by: Alan Stern > Signed-off-by: Paul E. McKenney > --- > .../ISA2+pooncelock+pooncelock+pombonce.litmus | 41 > ++ > 1 file changed, 41 insertions(+) > create mode 100644 > tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus Aren't these tests supposed to be described in litmus-tests/README? > diff --git > a/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus > b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus > new file mode 100644 > index ..7a39a0aaa976 > --- /dev/null > +++ > b/tools/memory-model/litmus-tests/ISA2+pooncelock+pooncelock+pombonce.litmus > @@ -0,0 +1,41 @@ > +C ISA2+pooncelock+pooncelock+pombonce.litmus > + > +(* > + * Result: Sometimes > + * > + * This test shows that the ordering provided by a lock-protected S > + * litmus test (P0() and P1()) are not visible to external process P2(). > + * This is likely to change soon. That last line may be premature. We haven't reached any consensus on how RISC-V will handle this. If RISC-V allows the test then the memory model can't forbid it. Alan > + *) > + > +{} > + > +P0(int *x, int *y, spinlock_t *mylock) > +{ > + spin_lock(mylock); > + WRITE_ONCE(*x, 1); > + WRITE_ONCE(*y, 1); > + spin_unlock(mylock); > +} > + > +P1(int *y, int *z, spinlock_t *mylock) > +{ > + int r0; > + > + spin_lock(mylock); > + r0 = READ_ONCE(*y); > + WRITE_ONCE(*z, 1); > + spin_unlock(mylock); > +} > + > +P2(int *x, int *z) > +{ > + int r1; > + int r2; > + > + r2 = READ_ONCE(*z); > + smp_mb(); > + r1 = READ_ONCE(*x); > +} > + > +exists (1:r0=1 /\ 2:r2=1 /\ 2:r1=0) >
Re: [PATCH 1/4] drm/atomic: integrate modeset lock with private objects
On Wed, Feb 21, 2018 at 09:54:49AM -0500, Rob Clark wrote: > On Wed, Feb 21, 2018 at 9:49 AM, Ville Syrjälä > wrote: > > On Wed, Feb 21, 2018 at 09:37:21AM -0500, Rob Clark wrote: > >> Follow the same pattern of locking as with other state objects. This > >> avoids boilerplate in the driver. > > > > I'm not sure we really want to do this. What if the driver wants a > > custom locking scheme for this state? > > That seems like something we want to discourage, ie. all the more > reason for this patch. > > There is no reason drivers could not split their global state into > multiple private objs's, each with their own lock, for more fine > grained locking. That is basically the only valid reason I can think > of for "custom locking". In i915 we have at least one case that would want something close to an rwlock. Any crtc lock is enough for read, need all of them for write. Though if we wanted to use private objs for that we might need to actually make the states refcounted as well, otherwise I can imagine we might land in some use-after-free issues once again. Maybe we could duplicate the state into per-crtc and global copies, but then we have to keep all of those in sync somehow which doesn't sound particularly pleasant. > > (And ofc drivers could add there own locks in addition to what is done > by core, but I'd rather look at that on a case by case basis, rather > than it being part of the boilerplate in each driver.) > > BR, > -R > > >> > >> Signed-off-by: Rob Clark > >> --- > >> drivers/gpu/drm/drm_atomic.c | 9 - > >> include/drm/drm_atomic.h | 5 + > >> 2 files changed, 13 insertions(+), 1 deletion(-) > >> > >> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > >> index fc8c4da409ff..004e621ab307 100644 > >> --- a/drivers/gpu/drm/drm_atomic.c > >> +++ b/drivers/gpu/drm/drm_atomic.c > >> @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj > >> *obj, > >> { > >> memset(obj, 0, sizeof(*obj)); > >> > >> + drm_modeset_lock_init(&obj->lock); > >> + > >> obj->state = state; > >> obj->funcs = funcs; > >> } > >> @@ -1093,6 +1095,7 @@ void > >> drm_atomic_private_obj_fini(struct drm_private_obj *obj) > >> { > >> obj->funcs->atomic_destroy_state(obj, obj->state); > >> + drm_modeset_lock_fini(&obj->lock); > >> } > >> EXPORT_SYMBOL(drm_atomic_private_obj_fini); > >> > >> @@ -1113,7 +1116,7 @@ struct drm_private_state * > >> drm_atomic_get_private_obj_state(struct drm_atomic_state *state, > >>struct drm_private_obj *obj) > >> { > >> - int index, num_objs, i; > >> + int index, num_objs, i, ret; > >> size_t size; > >> struct __drm_private_objs_state *arr; > >> struct drm_private_state *obj_state; > >> @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct > >> drm_atomic_state *state, > >> if (obj == state->private_objs[i].ptr) > >> return state->private_objs[i].state; > >> > >> + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); > >> + if (ret) > >> + return ERR_PTR(ret); > >> + > >> num_objs = state->num_private_objs + 1; > >> size = sizeof(*state->private_objs) * num_objs; > >> arr = krealloc(state->private_objs, size, GFP_KERNEL); > >> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h > >> index 09076a625637..9ae53b73c9d2 100644 > >> --- a/include/drm/drm_atomic.h > >> +++ b/include/drm/drm_atomic.h > >> @@ -218,6 +218,11 @@ struct drm_private_state_funcs { > >> * &drm_modeset_lock is required to duplicate and update this object's > >> state. > >> */ > >> struct drm_private_obj { > >> + /** > >> + * @lock: Modeset lock to protect the state object. > >> + */ > >> + struct drm_modeset_lock lock; > >> + > >> /** > >>* @state: Current atomic state for this driver private object. > >>*/ > >> -- > >> 2.14.3 > >> > >> ___ > >> dri-devel mailing list > >> dri-de...@lists.freedesktop.org > >> https://lists.freedesktop.org/mailman/listinfo/dri-devel > > > > -- > > Ville Syrjälä > > Intel OTC -- Ville Syrjälä Intel OTC
Re: [PATCH 2/3] platform/chrome: cros_ec_debugfs: Add PD port info to debugfs
On Wed, Feb 21, 2018 at 4:49 PM, Enric Balletbo i Serra wrote: > From: Shawn Nematbakhsh > > Add info useful for debugging USB-PD port state. This patch mixes up at least three things. Split it accordingly or drop unrelated changes. -- With Best Regards, Andy Shevchenko
Re: [PATCH v2 08/10] drm/panel: Add Huarui LHR050H41 panel driver
Hi Maxime, I love your patch! Perhaps something to improve: [auto build test WARNING on ] url: https://github.com/0day-ci/linux/commits/Maxime-Ripard/drm-sun4i-Allwinner-MIPI-DSI-support/20180221-203150 base: reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> drivers/gpu/drm/panel/panel-huarui-lhr050h41.c:69:24: sparse: symbol >> 'lhr050h41_init' was not declared. Should it be Please review and possibly fold the followup patch. --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
[RFC PATCH] drm/panel: lhr050h41_init[] can be static
Fixes: dcfac3b68dfb ("drm/panel: Add Huarui LHR050H41 panel driver") Signed-off-by: Fengguang Wu --- panel-huarui-lhr050h41.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panel/panel-huarui-lhr050h41.c b/drivers/gpu/drm/panel/panel-huarui-lhr050h41.c index f73d484..f71030e 100644 --- a/drivers/gpu/drm/panel/panel-huarui-lhr050h41.c +++ b/drivers/gpu/drm/panel/panel-huarui-lhr050h41.c @@ -66,7 +66,7 @@ struct lhr050h41_instr { }, \ } -struct lhr050h41_instr lhr050h41_init[] = { +static struct lhr050h41_instr lhr050h41_init[] = { LHR050H41_SWITCH_PAGE_INSTR(3), LHR050H41_COMMAND_INSTR(0x01, 0x00), LHR050H41_COMMAND_INSTR(0x02, 0x00),
[PATCH v2 17/17] selftests: ftrace: Add a testcase for array type with kprobe_event
Add a testcase for array type with kprobe event. This tests good/bad syntax combinations and also the traced data is correct in several way. If the kernel doesn't support array type, it skips the test as UNSUPPORTED. Signed-off-by: Masami Hiramatsu --- .../ftrace/test.d/kprobe/kprobe_args_array.tc | 75 1 file changed, 75 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_array.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_array.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_array.tc new file mode 100644 index ..27c9628c1fff --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_array.tc @@ -0,0 +1,75 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Kprobe event array argument + +[ -f kprobe_events ] || exit_unsupported # this is configurable + +grep -q "\[\]" README || exit_unsupported # version issue + +GOODSYM="_sdata" +if ! grep -qw ${GOODSYM} /proc/kallsyms ; then + GOODSYM="create_trace_kprobe" +fi +case `uname -m` in +x86_64) + ARG2=%si + OFFS=8 +;; +i[3456]86) + ARG2=%cx + OFFS=4 +;; +aarch64) + ARG2=%x1 + OFFS=8 +;; +arm*) + ARG2=%r1 + OFFS=4 +;; +*) + echo "Please implement other architecture here" + exit_untested +esac + +create_testprobe() { # args + echo "p:testprobe create_trace_kprobe $*" > kprobe_events +} + +echo 0 > events/enable +echo > kprobe_events + +: "Syntax test" +create_testprobe "+0(${ARG2}):x8[1] +0(${ARG2}):s16[1] +0(${ARG2}):u32[1]" +create_testprobe "+0(${ARG2}):x64[1] +0(${ARG2}):symbol[1]" +create_testprobe "+0(${ARG2}):b2@3/8[1] +0(${ARG2}):string[1]" +create_testprobe "+0(${ARG2}):x8[64] @${GOODSYM}:x8[4]" + +! create_testprobe "${ARG2}:x8[1]" # Can not use array type on register +! create_testprobe "\$comm:x8[1]" # Can not use array type on \$comm +! create_testprobe "\$comm:string[1]" # No, even if it is string array +! create_testprobe "+0(${ARG2}):x64[0]" # array size >= 1 +! create_testprobe "+0(${ARG2}):x64[65]" # array size <= 64 + +: "Test get argument (1)" +create_testprobe "arg1=+0(${ARG2}):string[1]" > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo test >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1={\"test\"}" +echo 0 > events/kprobes/testprobe/enable + +: "Test get argument (2)" +create_testprobe "arg1=+0(${ARG2}):string[3]" > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo foo bar buzz >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1={\"foo\",\"bar\",\"buzz\"}" +echo 0 > events/kprobes/testprobe/enable + +: "Test get argument (3)" +create_testprobe "arg1=+0(+0(${ARG2})):u8[4]" > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo 1234 >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1={49,50,51,52}" # ascii code +echo 0 > events/kprobes/testprobe/enable + +echo > kprobe_events
Re: [PATCH 0/6] DISCONTIGMEM support for PPC32
Le 21/02/2018 à 15:42, Jonathan Neuschäfer a écrit : Hi, On Wed, Feb 21, 2018 at 08:06:10AM +0100, Christophe LEROY wrote: Le 20/02/2018 à 17:14, Jonathan Neuschäfer a écrit : This patchset adds support for DISCONTIGMEM on 32-bit PowerPC. This is required to properly support the Nintendo Wii's memory layout, in which there are two blocks of RAM and MMIO in the middle. Previously, this memory layout was handled by code that joins the two RAM blocks into one, reserves the MMIO hole, and permits allocations of reserved memory in ioremap. This hack didn't work with resource-based allocation (as used for example in the GPIO driver for Wii[1]), however. After this patchset, users of the Wii can either select CONFIG_FLATMEM to get the old behaviour, or CONFIG_DISCONTIGMEM to get the new behaviour. My question might me stupid, as I don't know PCC64 in deep, but when looking at page_is_ram() in arch/powerpc/mm/mem.c, I have the feeling the PPC64 implements ram by blocks. Isn't it what you are trying to achieve ? Wouldn't it be feasible to map to what's done in PPC64 for PPC32 ? Using page_is_ram in __ioremap_caller and the same memblock-based approach that's used on PPC64 on PPC32 *should* work, but I think due to the following line in initmem_init, it won't: memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0); Can't we just fix that ? Christophe Thanks, Jonathan Neuschäfer
[PATCH v2 15/17] selftests: ftrace: Add a testcase for symbol type
Add a testcase for symbol type with kprobe event. This tests good/bad syntax combinations and also the traced data. If the kernel doesn't support symbol type, it skips the test as UNSUPPORTED. Signed-off-by: Masami Hiramatsu --- .../ftrace/test.d/kprobe/kprobe_args_symbol.tc | 73 1 file changed, 73 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_symbol.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_symbol.tc new file mode 100644 index ..a5820b175df5 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_symbol.tc @@ -0,0 +1,73 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Kprobe event argument symbol type + +[ -f kprobe_events ] || exit_unsupported # this is configurable + +grep -qe "type:.* symbol" README || exit_unsupported # version issue + +echo 0 > events/enable +echo > kprobe_events + +PROBEFUNC="vfs_read" +GOODREG= +BADREG= +GOODSYM="_sdata" +if ! grep -qw ${GOODSYM} /proc/kallsyms ; then + GOODSYM=$PROBEFUNC +fi + +case `uname -m` in +x86_64|i[3456]86) + GOODREG=%ax + BADREG=%ex +;; +aarch64) + GOODREG=%x0 + BADREG=%ax +;; +arm*) + GOODREG=%r0 + BADREG=%ax +;; +*) + echo "Please implement other architecture here" + exit_untested +esac + +test_goodarg() # Good-args +{ + while [ "$1" ]; do +echo "p ${PROBEFUNC} $1" > kprobe_events +shift 1 + done; +} + +test_badarg() # Bad-args +{ + while [ "$1" ]; do +! echo "p ${PROBEFUNC} $1" > kprobe_events +shift 1 + done; +} + +echo > kprobe_events + +: "Symbol type" +test_goodarg "${GOODREG}:symbol" "@${GOODSYM}:symbol" "@${GOODSYM}+10:symbol" \ +"\$stack0:symbol" "+0(\$stack):symbol" +test_badarg "\$comm:symbol" + +: "Retval with symbol type" +echo "r ${PROBEFUNC} \$retval:symbol" > kprobe_events + +echo > kprobe_events + +: "Test get symbol" +echo 'p:testprobe create_trace_kprobe $stack0:symbol' > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo test >> kprobe_events +tail -n 1 trace | grep -q "arg1=trace_run_command" + +echo 0 > events/enable +echo > kprobe_events
[PATCH v2 16/17] selftests: ftrace: Add a testcase for $argN with kprobe_event
Add a testcase for array type with kprobe event. This tests whether the traced data is correct or not. If the kernel doesn't support array type, it skips the test as UNSUPPORTED. Signed-off-by: Masami Hiramatsu --- .../ftrace/test.d/kprobe/kprobe_args_argN.tc | 25 1 file changed, 25 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_argN.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_argN.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_argN.tc new file mode 100644 index ..d5c5c8c3a51e --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_argN.tc @@ -0,0 +1,25 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Kprobe event argN argument + +[ -f kprobe_events ] || exit_unsupported # this is configurable + +grep -q "arg" README || exit_unsupported # version issue + +echo 0 > events/enable +echo > kprobe_events + +: "Test bad pattern : arg0 is not allowed" +! echo 'p:testprobe create_trace_kprobe $arg0' > kprobe_events + +: "Test get argument" +echo 'p:testprobe create_trace_kprobe $arg1' > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo test >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1=0x1" + +! echo test test test >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1=0x3" + +echo 0 > events/enable +echo > kprobe_events
Re: [PATCH] Make kernel taint on invalid module signatures configurable
On Tue, 2018-02-20 at 20:37 +, Matthew Garrett wrote: > On Tue, Feb 20, 2018 at 11:21 AM Jessica Yu wrote: [...] > > In any case, I think I'd be willing to merge it as a module_param made > > available under CONFIG_MODULE_SIG=y (rather than as a new separate config > > option), while preserving the default behavior of tainting on > > unsigned/invalidly signed module loads (so let's keep the param parts of > > your patch). I think it makes sense to consider the turning-off-the-taint > > param as a behavioral tweak under CONFIG_MODULE_SIG. Then you could turn > > off the tainting behavior on the kernel command line, would this sufficient > > enough for your use cases? > > I think that's probably not practical - distributions often aren't in > control of the kernel command line after initial installation, so they'd > end up with different behaviour depending on whether a machine was a clean > install or not (which is why several things that are module_params have > defaults controlled by additional kernel config options) Indeed. So long as Debian doesn't do module signing, the default behaviour in our kernel images will need to be that they don't complain about lack of signatures. [...] > > > 1) Distributions that build out of tree kernel modules and don't have > > > infrastructure to sign them will end up with kernel taint. That's > > > something > > > that can be resolved by implementing that infrastructure. > > > 2) End-users who build out of tree kernel modules will end up with kernel > > > taint and will file bugs. This cannot be fixed but will increase > > > distribution load anyway. > > I thought these two cases (particularly #2) were the very situations > > where distros might find the unsigned module taint useful (especially > > in the use case where you do benefit from module signatures). From my > > understanding, the unsigned module taint is intended to be useful when > > looking at crashes/OOPses, to provide a clear indication of whether or > > not a developer could reliably debug the crash, or choose to tread > > carefully, because the end-user has loaded an unsigned/out-of-tree > > module that wasn't signed/shipped by the distribution. Is the taint > > just not useful to distros in this manner anymore? > > The module list is usually sufficient for that - users tend not to replace > individual distribution modules without rebuilding their entire kernel. And we already have an O (out-of-tree) taint flag. Ben. -- Ben Hutchings [W]e found...that it wasn't as easy to get programs right as we had thought. ... I realized that a large part of my life from then on was going to be spent in finding mistakes in my own programs. - Maurice Wilkes, 1949 signature.asc Description: This is a digitally signed message part
[PATCH] staging: typec: handle vendor defined part and modify drp toggling flow
From: ShuFanLee Handle vendor defined behavior in tcpci_init, tcpci_set_vconn and export tcpci_irq. More operations can be extended in tcpci_data if needed. According to TCPCI specification, 4.4.5.2 ROLE_CONTROL, TCPC shall not start DRP toggling until subsequently the TCPM writes to the COMMAND register to start DRP toggling. DRP toggling flow is chagned as following: - Write DRP = 0 & Rd/Rd - Write DRP = 1 - Set LOOK4CONNECTION command Signed-off-by: ShuFanLee --- drivers/staging/typec/tcpci.c | 128 +- drivers/staging/typec/tcpci.h | 13 + 2 files changed, 115 insertions(+), 26 deletions(-) patch changelogs between v1 & v2 - Remove unnecessary i2c_client in the structure of tcpci - Rename structure of tcpci_vendor_data to tcpci_data - Not exporting tcpci read/write wrappers but register i2c regmap in glue driver - Add set_vconn ops in tcpci_data (It is necessary for RT1711H to enable/disable idle mode before disabling/enabling vconn) - Export tcpci_irq so that vendor can call it in their own IRQ handler patch changelogs between v2 & v3 - Change the return type of tcpci_irq from int to irqreturn_t diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c index 9bd4412..4959c69 100644 --- a/drivers/staging/typec/tcpci.c +++ b/drivers/staging/typec/tcpci.c @@ -21,7 +21,6 @@ struct tcpci { struct device *dev; - struct i2c_client *client; struct tcpm_port *port; @@ -30,6 +29,12 @@ struct tcpci { bool controls_vbus; struct tcpc_dev tcpc; + struct tcpci_data *data; +}; + +struct tcpci_chip { + struct tcpci *tcpci; + struct tcpci_data data; }; static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc) @@ -37,8 +42,7 @@ static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc) return container_of(tcpc, struct tcpci, tcpc); } -static int tcpci_read16(struct tcpci *tcpci, unsigned int reg, - u16 *val) +static int tcpci_read16(struct tcpci *tcpci, unsigned int reg, u16 *val) { return regmap_raw_read(tcpci->regmap, reg, val, sizeof(u16)); } @@ -98,8 +102,10 @@ static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc) static int tcpci_start_drp_toggling(struct tcpc_dev *tcpc, enum typec_cc_status cc) { + int ret; struct tcpci *tcpci = tcpc_to_tcpci(tcpc); - unsigned int reg = TCPC_ROLE_CTRL_DRP; + unsigned int reg = (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) | + (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT); switch (cc) { default: @@ -117,7 +123,19 @@ static int tcpci_start_drp_toggling(struct tcpc_dev *tcpc, break; } - return regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg); + ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg); + if (ret < 0) + return ret; + usleep_range(500, 1000); + reg |= TCPC_ROLE_CTRL_DRP; + ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg); + if (ret < 0) + return ret; + ret = regmap_write(tcpci->regmap, TCPC_COMMAND, + TCPC_CMD_LOOK4CONNECTION); + if (ret < 0) + return ret; + return 0; } static enum typec_cc_status tcpci_to_typec_cc(unsigned int cc, bool sink) @@ -178,6 +196,16 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable) struct tcpci *tcpci = tcpc_to_tcpci(tcpc); int ret; + /* Handle vendor set vconn */ + if (tcpci->data) { + if (tcpci->data->set_vconn) { + ret = tcpci->data->set_vconn(tcpci, tcpci->data, +enable); + if (ret < 0) + return ret; + } + } + ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL, enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0); if (ret < 0) @@ -323,6 +351,15 @@ static int tcpci_init(struct tcpc_dev *tcpc) if (time_after(jiffies, timeout)) return -ETIMEDOUT; + /* Handle vendor init */ + if (tcpci->data) { + if (tcpci->data->init) { + ret = tcpci->data->init(tcpci, tcpci->data); + if (ret < 0) + return ret; + } + } + /* Clear all events */ ret = tcpci_write16(tcpci, TCPC_ALERT, 0x); if (ret < 0) @@ -344,9 +381,15 @@ static int tcpci_init(struct tcpc_dev *tcpc) return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg); } -static irqreturn_t tcpci_irq(int irq, void *dev_id) +static irqreturn_t _tcpci_irq(int irq, void *dev_id) { struct tcpci *tcpci = dev_id; + + return tcpci_irq(tcpci); +} + +irqreturn_t tcpci_irq(struct tcpci *tcp
[PATCH v2 14/17] tracing: probeevent: Add array type support
Add array type support for probe events. This allows user to get arraied types from memory address. The array type syntax is TYPE[N] Where TYPE is one of types (u8/16/32/64,s8/16/32/64, x8/16/32/64, symbol, string) and N is a fixed value less than 64. The string array type is a bit different from other types. For other base types, [1] is equal to (e.g. +0(%di):x32[1] is same as +0(%di):x32.) But string[1] is not equal to string. The string type itself represents "char array", but string array type represents "char * array". So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string. Signed-off-by: Masami Hiramatsu --- Changes in v2: - Add array description in README file - Fix to init s3 code out of loop. - Fix to proceed code when the last code is OP_ARRAY. - Add string array type and bitfield array type. --- Documentation/trace/kprobetrace.txt | 13 kernel/trace/trace.c|3 + kernel/trace/trace_probe.c | 129 +++ kernel/trace/trace_probe.h | 14 kernel/trace/trace_probe_tmpl.h | 63 +++-- 5 files changed, 183 insertions(+), 39 deletions(-) diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 1d082f8ffeee..8bf752dfc072 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -65,9 +65,22 @@ in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32' or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and x86-64 uses x64). +These value types can be an array. To record array data, you can add '[N]' +(where N is a fixed number, less than 64) to the base type. +E.g. 'x16[4]' means an array of x16 (2bytes hex) with 4 elements. +Note that the array can be applied to memory type fetchargs, you can not +apply it to registers/stack-entries etc. (for example, '$stack1:x8[8]' is +wrong, but '+8($stack):x8[8]' is OK.) + String type is a special type, which fetches a "null-terminated" string from kernel space. This means it will fail and store NULL if the string container has been paged out. +The string array type is a bit different from other types. For other base +types, [1] is equal to (e.g. +0(%di):x32[1] is same +as +0(%di):x32.) But string[1] is not equal to string. The string type itself +represents "char array", but string array type represents "char * array". +So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string. + Bitfield is another special type, which takes 3 parameters, bit-width, bit- offset, and container-size (usually 32). The syntax is; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 94423529b986..cdf3931cea57 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4610,7 +4610,8 @@ static const char readme_msg[] = "\t fetcharg: %, @, @[+|-],\n" "\t $stack, $stack, $retval, $comm, $arg\n" "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" - "\t b@/\n" + "\t b@/,\n" + "\t []\n" #endif " events/\t\t- Directory containing all trace event subsystems:\n" " enable\t\t- Write 0/1 to enable/disable tracing of all events\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index f4b83927d6c0..8b019125fbe4 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -365,9 +365,9 @@ static int __parse_bitfield_probe_arg(const char *bf, int traceprobe_parse_probe_arg(char *arg, ssize_t *size, struct probe_arg *parg, unsigned int flags) { - struct fetch_insn *code, *tmp = NULL; - const char *t; - int ret; + struct fetch_insn *code, *scode, *tmp = NULL; + char *t, *t2; + int ret, len; if (strlen(arg) > MAX_ARGSTR_LEN) { pr_info("Argument is too long.: %s\n", arg); @@ -378,24 +378,42 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, pr_info("Failed to allocate memory for command '%s'.\n", arg); return -ENOMEM; } - t = strchr(parg->comm, ':'); + t = strchr(arg, ':'); if (t) { - arg[t - parg->comm] = '\0'; - t++; + *t = '\0'; + t2 = strchr(++t, '['); + if (t2) { + *t2 = '\0'; + parg->count = simple_strtoul(t2 + 1, &t2, 0); + if (strcmp(t2, "]") || parg->count == 0) + return -EINVAL; + if (parg->count > MAX_ARRAY_LEN) + return -E2BIG; + } } /* * The default type of $comm should be "string", and it can't be * dereferenced. */ if (!t && strcmp(arg, "$comm") == 0) - t = "string"; - parg->type = find_fetch_type(t); + p
RE: [RFC PATCH] mmc: sdhci-of-arasan: Add auto tuning support for ZynqMP Platform
Hi Adrian, > -Original Message- > From: Manish Narani > Sent: Wednesday, February 21, 2018 11:39 AM > To: Adrian Hunter ; michal.si...@xilinx.com; > ulf.hans...@linaro.org; linux-arm-ker...@lists.infradead.org; linux- > m...@vger.kernel.org; linux-kernel@vger.kernel.org; > devicet...@vger.kernel.org; mark.rutl...@arm.com; robh...@kernel.org > Cc: Anirudha Sarangi ; Srinivas Goud > > Subject: RE: [RFC PATCH] mmc: sdhci-of-arasan: Add auto tuning support for > ZynqMP Platform > > Hi Adrian, > > > > -Original Message- > > From: Adrian Hunter [mailto:adrian.hun...@intel.com] > > Sent: Friday, February 16, 2018 7:37 PM > > To: Manish Narani ; michal.si...@xilinx.com; > > ulf.hans...@linaro.org; linux-arm-ker...@lists.infradead.org; linux- > > m...@vger.kernel.org; linux-kernel@vger.kernel.org; > > devicet...@vger.kernel.org; mark.rutl...@arm.com; robh...@kernel.org > > Cc: Anirudha Sarangi ; Srinivas Goud > > ; Manish Narani > > Subject: Re: [RFC PATCH] mmc: sdhci-of-arasan: Add auto tuning support > > for ZynqMP Platform > > > > On 30/01/18 20:14, Manish Narani wrote: > > > This patch adds support of SD auto tuning for ZynqMP platform. Auto > > > tuning sequence sends tuning block to card when operating in UHS-1 > > > modes. This resets the DLL and sends CMD19/CMD21 as a part of the > > > auto tuning process. Once the auto tuning process gets completed, > > > reset the DLL to load the newly obtained SDHC tuned tap value. > > > > How is this different from: > > 1. reset the dll > > 2. call sdhci_execute_tuning > > 3. reset the dll > > Below is my take on your above comments: - 'Reset the dll' is a platform specific call inside 'arasan_zynqmp_execute_tuning' which is implemented in sdhci-of-arasan.c - 'arasan_zynqmp_execute_tuning' is called from 'sdhci_execute_tuning' as a platform_execute_tuning routine - So to keep 'DLL reset' routine called from sdhci-of-arasan.c, I have implemented the execute_tuning in sdhci-of-arasan.c Alternative way (Please review): - Define a host->quirk2 bit (SDHCI_QUIRK2_DLL_RESET_NEEDED) in sdhci-of-arasan.c indicating DLL reset needed while tuning operation - Call 'dll reset' routine before and after __sdhci_execute_tuning() in sdhci.c when a host->quirk2 bit (SDHCI_QUIRK2_DLL_RESET_NEEDED) is set Thanks, Manish > Thanks for your comments. I am looking into this. I will check and let you > know on the same. > > Thanks, > - Manish > > > > > > > Signed-off-by: Manish Narani > > > --- > > > .../devicetree/bindings/mmc/arasan,sdhci.txt | 1 + > > > drivers/mmc/host/sdhci-of-arasan.c | 219 > > - > > > 2 files changed, 219 insertions(+), 1 deletion(-) > > > > > > diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > index 60481bf..7d29751 100644 > > > --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt > > > @@ -14,6 +14,7 @@ Required Properties: > > > - "arasan,sdhci-4.9a": generic Arasan SDHCI 4.9a PHY > > > - "arasan,sdhci-5.1": generic Arasan SDHCI 5.1 PHY > > > - "rockchip,rk3399-sdhci-5.1", "arasan,sdhci-5.1": rk3399 eMMC > > > PHY > > > +- "xlnx,zynqmp-8.9a": Xilinx ZynqMP 8.9a PHY > > >For this device it is strongly suggested to include arasan,soc-ctl- > syscon. > > >- reg: From mmc bindings: Register location and length. > > >- clocks: From clock bindings: Handles to clock inputs. > > > diff --git a/drivers/mmc/host/sdhci-of-arasan.c > > > b/drivers/mmc/host/sdhci-of-arasan.c > > > index 0720ea7..7673db4 100644 > > > --- a/drivers/mmc/host/sdhci-of-arasan.c > > > +++ b/drivers/mmc/host/sdhci-of-arasan.c > > > @@ -24,15 +24,18 @@ > > > #include > > > #include > > > #include > > > +#include > > > #include > > > #include "sdhci-pltfm.h" > > > #include > > > +#include > > > > > > #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 > > > > > > #define VENDOR_ENHANCED_STROBE BIT(0) > > > > > > #define PHY_CLK_TOO_SLOW_HZ40 > > > +#define MAX_TUNING_LOOP40 > > > > > > /* > > > * On some SoCs the syscon area has a feature where the upper > > > 16-bits of @@ -88,6 +91,7 @@ struct sdhci_arasan_data { > > > struct sdhci_host *host; > > > struct clk *clk_ahb; > > > struct phy *phy; > > > + u32 device_id; > > > boolis_phy_on; > > > > > > struct clk_hw sdcardclk_hw; > > > @@ -157,6 +161,213 @@ static int sdhci_arasan_syscon_write(struct > > sdhci_host *host, > > > return ret; > > > } > > > > > > +/** > > > + * arasan_zynqmp_dll_reset - Issue the DLL reset. > > > + * @deviceid: Unique Id of device > > > + */ > > > +void zynqmp_dll_reset(u8 deviceid) > > > +{ > > > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > > > + > > > + if (!ee
[PATCH v2 13/17] tracing: probeevent: Add $argN for accessing function args
Add $argN special fetch variable for accessing function arguments. This allows user to trace the Nth argument easily at the function entry. Note that this returns most probably assignment of registers and stacks. In some case, it may not work well. If you need to access correct registers or stacks you should use perf-probe. Signed-off-by: Masami Hiramatsu --- Changes in v2: - Add $argN in README file - Make N start from 1 as same as auto-generate event argument names. --- Documentation/trace/kprobetrace.txt | 10 ++ kernel/trace/trace.c|2 +- kernel/trace/trace_kprobe.c | 18 +- kernel/trace/trace_probe.c | 36 ++- kernel/trace/trace_probe.h |9 - kernel/trace/trace_uprobe.c |2 +- 6 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index d49381f2e411..1d082f8ffeee 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -43,16 +43,18 @@ Synopsis of kprobe_events @SYM[+|-offs]: Fetch memory at SYM +|- offs (SYM should be a data symbol) $stackN : Fetch Nth entry of stack (N >= 0) $stack : Fetch stack address. - $retval : Fetch return value.(*) + $argN: Fetch the Nth function argument. (N >= 1) (*1) + $retval : Fetch return value.(*2) $comm: Fetch current task comm. - +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) + +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(*3) NAME=FETCHARG : Set NAME as the argument name of FETCHARG. FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (x8/x16/x32/x64), "string" and bitfield are supported. - (*) only for return probe. - (**) this is useful for fetching a field of data structures. + (*1) only for the probe on function entry (offs == 0). + (*2) only for return probe. + (*3) this is useful for fetching a field of data structures. Types - diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8f08811d15b8..94423529b986 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4608,7 +4608,7 @@ static const char readme_msg[] = #endif "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @, @[+|-],\n" - "\t $stack, $stack, $retval, $comm\n" + "\t $stack, $stack, $retval, $comm, $arg\n" "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t b@/\n" #endif diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5025907e0c99..df39c7d5dd4c 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -490,13 +490,15 @@ static int create_trace_kprobe(int argc, char **argv) unsigned long offset = 0; void *addr = NULL; char buf[MAX_EVENT_NAME_LEN]; + unsigned int flags = TPARG_FL_KERNEL; /* argc must be >= 1 */ if (argv[0][0] == 'p') is_return = false; - else if (argv[0][0] == 'r') + else if (argv[0][0] == 'r') { is_return = true; - else if (argv[0][0] == '-') + flags |= TPARG_FL_RETURN; + } else if (argv[0][0] == '-') is_delete = true; else { pr_info("Probe definition must be started with 'p', 'r' or" @@ -579,8 +581,9 @@ static int create_trace_kprobe(int argc, char **argv) pr_info("Failed to parse either an address or a symbol.\n"); return ret; } - if (offset && is_return && - !kprobe_on_func_entry(NULL, symbol, offset)) { + if (kprobe_on_func_entry(NULL, symbol, offset)) + flags |= TPARG_FL_FENTRY; + if (offset && is_return && !(flags & TPARG_FL_FENTRY)) { pr_info("Given offset is not valid for return probe.\n"); return -EINVAL; } @@ -650,7 +653,7 @@ static int create_trace_kprobe(int argc, char **argv) /* Parse fetch argument */ ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg, -is_return, true); +flags); if (ret) { pr_info("Parse error at argument[%d]. (%d)\n", i, ret); goto error; @@ -890,6 +893,11 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, case FETCH_OP_COMM: val = (unsigned long)current->comm; break; +#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API + case FETCH_OP_ARG: + val
[PATCH v2 12/17] x86: ptrace: Add function argument access API
Add regs_get_argument() which returns N th argument of the function call. Note that this chooses most probably assignment, in some case it can be incorrect (e.g. passing data structure or floating point etc.) This is expected to be called from kprobes or ftrace with regs where the top of stack is the return address. Signed-off-by: Masami Hiramatsu --- arch/Kconfig |7 +++ arch/x86/Kconfig |1 + arch/x86/include/asm/ptrace.h | 38 ++ 3 files changed, 46 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 76c0b54443b1..4126ad4b122c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -272,6 +272,13 @@ config HAVE_REGS_AND_STACK_ACCESS_API declared in asm/ptrace.h For example the kprobes-based event tracer needs this API. +config HAVE_FUNCTION_ARG_ACCESS_API + bool + help + This symbol should be selected by an architecure if it supports + the API needed to access function arguments from pt_regs, + declared in asm/ptrace.h + config HAVE_CLK bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 552b3d0eae36..eb0cad381ace 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -176,6 +176,7 @@ config X86 select HAVE_PERF_USER_STACK_DUMP select HAVE_RCU_TABLE_FREE select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_RELIABLE_STACKTRACE if X86_64 && UNWINDER_FRAME_POINTER && STACK_VALIDATION select HAVE_STACK_VALIDATIONif X86_64 select HAVE_SYSCALL_TRACEPOINTS diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 6de1fd3d0097..c2304b25e2fd 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -256,6 +256,44 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, return 0; } +/** + * regs_get_kernel_argument() - get Nth function argument in kernel + * @regs: pt_regs of that context + * @n: function argument number (start from 0) + * + * regs_get_argument() returns @n th argument of the function call. + * Note that this chooses most probably assignment, in some case + * it can be incorrect. + * This is expected to be called from kprobes or ftrace with regs + * where the top of stack is the return address. + */ +static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs, +unsigned int n) +{ + static const unsigned int argument_offs[] = { +#ifdef __i386__ + offsetof(struct pt_regs, ax), + offsetof(struct pt_regs, cx), + offsetof(struct pt_regs, dx), +#define NR_REG_ARGUMENTS 3 +#else + offsetof(struct pt_regs, di), + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, dx), + offsetof(struct pt_regs, cx), + offsetof(struct pt_regs, r8), + offsetof(struct pt_regs, r9), +#define NR_REG_ARGUMENTS 6 +#endif + }; + + if (n >= NR_REG_ARGUMENTS) { + n -= NR_REG_ARGUMENTS - 1; + return regs_get_kernel_stack_nth(regs, n); + } else + return regs_get_register(regs, argument_offs[n]); +} + #define arch_has_single_step() (1) #ifdef CONFIG_X86_DEBUGCTLMSR #define arch_has_block_step() (1)
Re: [PATCH] tools/memory-model: remove rb-dep, smp_read_barrier_depends, and lockless_dereference
On Fri, 16 Feb 2018, Paul E. McKenney wrote: > On Fri, Feb 16, 2018 at 05:22:55PM -0500, Alan Stern wrote: > > Since commit 76ebbe78f739 ("locking/barriers: Add implicit > > smp_read_barrier_depends() to READ_ONCE()") was merged for the 4.15 > > kernel, it has not been necessary to use smp_read_barrier_depends(). > > Similarly, commit 59ecbbe7b31c ("locking/barriers: Kill > > lockless_dereference()") removed lockless_dereference() from the > > kernel. > > > > Since these primitives are no longer part of the kernel, they do not > > belong in the Linux Kernel Memory Consistency Model. This patch > > removes them, along with the internal rb-dep relation, and updates the > > revelant documentation. > > > > Signed-off-by: Alan Stern > > I queued this, but would welcome an update that addressed Akira's > feedback as appropriate. Is it too late to send a v2 of this patch? I didn't want to do it before now because the issue raised by Andrea wasn't settled. (Some could claim that it still isn't fully settled...) Alan
[PATCH v2 11/17] tracing: probeevent: Add symbol type
Add "symbol" type to probeevent, which is an alias of u32 or u64 (depends on BITS_PER_LONG). This shows the result value in symbol+offset style. This type is only available with kprobe events. Signed-off-by: Masami Hiramatsu --- Changes in v2: - Add symbol type to README file. --- Documentation/trace/kprobetrace.txt |3 +++ kernel/trace/trace.c|2 +- kernel/trace/trace_probe.c |8 kernel/trace/trace_probe.h | 12 +--- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 1a3a3d6bc2a8..d49381f2e411 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt @@ -62,6 +62,7 @@ respectively. 'x' prefix implies it is unsigned. Traced arguments are shown in decimal ('s' and 'u') or hexadecimal ('x'). Without type casting, 'x32' or 'x64' is used depends on the architecture (e.g. x86-32 uses x32, and x86-64 uses x64). + String type is a special type, which fetches a "null-terminated" string from kernel space. This means it will fail and store NULL if the string container has been paged out. @@ -70,6 +71,8 @@ offset, and container-size (usually 32). The syntax is; b@/ +Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG) +which shows given pointer in "symbol+offset" style. For $comm, the default type is "string"; any other type is invalid. diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 20a2300ae4e8..8f08811d15b8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4609,7 +4609,7 @@ static const char readme_msg[] = "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @, @[+|-],\n" "\t $stack, $stack, $retval, $comm\n" - "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string,\n" + "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t b@/\n" #endif " events/\t\t- Directory containing all trace event subsystems:\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 8d43f377143d..f41a2989130c 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -58,6 +58,13 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x16, u16, "0x%x") DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x") DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx") +int PRINT_TYPE_FUNC_NAME(symbol)(struct trace_seq *s, void *data, void *ent) +{ + trace_seq_printf(s, "%pS", (void *)*(unsigned long *)data); + return !trace_seq_has_overflowed(s); +} +const char PRINT_TYPE_FMT_NAME(symbol)[] = "%pS"; + /* Print type function for string type */ int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent) { @@ -91,6 +98,7 @@ static const struct fetch_type probe_fetch_types[] = { ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0), ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0), ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0), + ASSIGN_FETCH_TYPE_ALIAS(symbol, ADDR_FETCH_TYPE, ADDR_FETCH_TYPE, 0), ASSIGN_FETCH_TYPE_END }; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 3bc43c1ce628..ef477bd8468a 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -157,6 +157,7 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(x32); DECLARE_BASIC_PRINT_TYPE_FUNC(x64); DECLARE_BASIC_PRINT_TYPE_FUNC(string); +DECLARE_BASIC_PRINT_TYPE_FUNC(symbol); /* Default (unsigned long) fetch type */ #define __DEFAULT_FETCH_TYPE(t) x##t @@ -164,6 +165,10 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(string); #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG) #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE) +#define __ADDR_FETCH_TYPE(t) u##t +#define _ADDR_FETCH_TYPE(t) __ADDR_FETCH_TYPE(t) +#define ADDR_FETCH_TYPE _ADDR_FETCH_TYPE(BITS_PER_LONG) + #define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ {.name = _name, \ .size = _size, \ @@ -172,13 +177,14 @@ DECLARE_BASIC_PRINT_TYPE_FUNC(string); .fmt = PRINT_TYPE_FMT_NAME(ptype), \ .fmttype = _fmttype, \ } - +#define _ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ + __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, #_fmttype) #define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \ - __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype) + _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, ptype) /* If ptype is an alias of atype, use this macro (show atype in format) */ #define ASSIGN_FETCH_TYPE_ALIAS(ptype, atype, ftype, sign) \ - __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #atype) + _ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, atype) #define ASSIGN_FETCH_TY
[PATCH v2 10/17] tracing: probeevent: Unify fetch_insn processing common part
Unify the fetch_insn bottom process (from stage 2: dereference indirect data) from kprobe and uprobe events, since those are mostly same. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c | 47 + kernel/trace/trace_probe_tmpl.h | 55 ++- kernel/trace/trace_uprobe.c | 43 +- 3 files changed, 63 insertions(+), 82 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ec20f0b56cfe..5025907e0c99 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -857,13 +857,18 @@ fetch_store_string(unsigned long addr, void *dest, void *base) return ret; } +static nokprobe_inline int +probe_mem_read(void *dest, void *src, size_t size) +{ + return probe_kernel_read(dest, src, size); +} + /* Note that we don't verify it, since the code does not come from user space */ static int process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, void *base) { unsigned long val; - int ret = 0; /* 1st stage: get value from context */ switch (code->op) { @@ -890,45 +895,7 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, } code++; - /* 2nd stage: dereference memory if needed */ - while (code->op == FETCH_OP_DEREF) { - ret = probe_kernel_read(&val, (void *)val + code->offset, - sizeof(val)); - if (ret) - return ret; - code++; - } - - /* 3rd stage: store value to buffer */ - if (unlikely(!dest)) { - if (code->op == FETCH_OP_ST_STRING) - return fetch_store_strlen(val + code->offset); - else - return -EILSEQ; - } - - switch (code->op) { - case FETCH_OP_ST_RAW: - fetch_store_raw(val, code, dest); - break; - case FETCH_OP_ST_MEM: - probe_kernel_read(dest, (void *)val + code->offset, code->size); - break; - case FETCH_OP_ST_STRING: - ret = fetch_store_string(val + code->offset, dest, base); - break; - default: - return -EILSEQ; - } - code++; - - /* 4th stage: modify stored value if needed */ - if (code->op == FETCH_OP_MOD_BF) { - fetch_apply_bitfield(code, dest); - code++; - } - - return code->op == FETCH_OP_END ? ret : -EILSEQ; + return process_fetch_insn_bottom(code, val, dest, base); } NOKPROBE_SYMBOL(process_fetch_insn) diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h index d9aebd395a9d..32ae2fc78190 100644 --- a/kernel/trace/trace_probe_tmpl.h +++ b/kernel/trace/trace_probe_tmpl.h @@ -49,13 +49,66 @@ fetch_apply_bitfield(struct fetch_insn *code, void *buf) } /* - * This must be defined for each callsite. + * These functions must be defined for each callsite. * Return consumed dynamic data size (>= 0), or error (< 0). * If dest is NULL, don't store result and return required dynamic data size. */ static int process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, void *base); +static nokprobe_inline int fetch_store_strlen(unsigned long addr); +static nokprobe_inline int +fetch_store_string(unsigned long addr, void *dest, void *base); +static nokprobe_inline int +probe_mem_read(void *dest, void *src, size_t size); + +/* From the 2nd stage, routine is same */ +static nokprobe_inline int +process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val, + void *dest, void *base) +{ + int ret = 0; + + /* 2nd stage: dereference memory if needed */ + while (code->op == FETCH_OP_DEREF) { + ret = probe_mem_read(&val, (void *)val + code->offset, + sizeof(val)); + if (ret) + return ret; + code++; + } + + /* 3rd stage: store value to buffer */ + if (unlikely(!dest)) { + if (code->op == FETCH_OP_ST_STRING) + return fetch_store_strlen(val + code->offset); + else + return -EILSEQ; + } + + switch (code->op) { + case FETCH_OP_ST_RAW: + fetch_store_raw(val, code, dest); + break; + case FETCH_OP_ST_MEM: + probe_mem_read(dest, (void *)val + code->offset, code->size); + break; + case FETCH_OP_ST_STRING: + ret = fetch_store_string(val + code->offset, dest, base); + break; + default: + return -EILSEQ; + } + code++; + + /* 4th stage: modify stored value if needed */ +
[PATCH v2 08/17] tracing: probeevent: Return consumed bytes of dynamic area
Cleanup string fetching routine so that returns the consumed bytes of dynamic area and store the string information as data_loc format instead of data_rloc. This simplifies the fetcharg loop. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c | 51 +++--- kernel/trace/trace_probe.h | 26 --- kernel/trace/trace_probe_tmpl.h | 52 +- kernel/trace/trace_uprobe.c | 53 --- 4 files changed, 82 insertions(+), 100 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5dd2d470cc7e..ee41d5700e25 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -807,8 +807,8 @@ static const struct file_operations kprobe_profile_ops = { /* Kprobe specific fetch functions */ /* Return the length of string -- including null terminal byte */ -static nokprobe_inline void -fetch_store_strlen(unsigned long addr, void *dest) +static nokprobe_inline int +fetch_store_strlen(unsigned long addr) { mm_segment_t old_fs; int ret, len = 0; @@ -826,25 +826,22 @@ fetch_store_strlen(unsigned long addr, void *dest) pagefault_enable(); set_fs(old_fs); - if (ret < 0)/* Failed to check the length */ - *(u32 *)dest = 0; - else - *(u32 *)dest = len; + return (ret < 0) ? ret : len; } /* * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max * length and relative data location. */ -static nokprobe_inline void -fetch_store_string(unsigned long addr, void *dest) +static nokprobe_inline int +fetch_store_string(unsigned long addr, void *dest, void *base) { - int maxlen = get_rloc_len(*(u32 *)dest); - u8 *dst = get_rloc_data(dest); + int maxlen = get_loc_len(*(u32 *)dest); + u8 *dst = get_loc_data(dest, base); long ret; if (!maxlen) - return; + return -ENOMEM; /* * Try to get string again, since the string can be changed while @@ -854,19 +851,19 @@ fetch_store_string(unsigned long addr, void *dest) if (ret < 0) { /* Failed to fetch string */ dst[0] = '\0'; - *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); - } else { - *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest)); + ret = 0; } + *(u32 *)dest = make_data_loc(ret, (void *)dst - base); + return ret; } /* Note that we don't verify it, since the code does not come from user space */ static int process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, - bool pre) + void *base) { unsigned long val; - int ret; + int ret = 0; /* 1st stage: get value from context */ switch (code->op) { @@ -903,6 +900,13 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, } /* 3rd stage: store value to buffer */ + if (unlikely(!dest)) { + if (code->op == FETCH_OP_ST_STRING) + return fetch_store_strlen(val + code->offset); + else + return -EILSEQ; + } + switch (code->op) { case FETCH_OP_ST_RAW: fetch_store_raw(val, code, dest); @@ -911,10 +915,7 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, probe_kernel_read(dest, (void *)val + code->offset, code->size); break; case FETCH_OP_ST_STRING: - if (pre) - fetch_store_strlen(val + code->offset, dest); - else - fetch_store_string(val + code->offset, dest); + ret = fetch_store_string(val + code->offset, dest, base); break; default: return -EILSEQ; @@ -927,7 +928,7 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest, code++; } - return code->op == FETCH_OP_END ? 0 : -EILSEQ; + return code->op == FETCH_OP_END ? ret : -EILSEQ; } NOKPROBE_SYMBOL(process_fetch_insn) @@ -962,7 +963,7 @@ __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs, entry = ring_buffer_event_data(event); entry->ip = (unsigned long)tk->rp.kp.addr; - store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); + store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize); event_trigger_unlock_commit_regs(trace_file, buffer, event, entry, irq_flags, pc, regs); @@ -1011,7 +1012,7 @@ __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri, entry = ring_buffer_event_data(event); entry->func = (unsigned long)tk->rp.kp.ad
[PATCH v2 09/17] tracing: probeevent: Append traceprobe_ for exported function
Append traceprobe_ for exported function set_print_fmt() as same as other functions. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c |4 ++-- kernel/trace/trace_probe.c |2 +- kernel/trace/trace_probe.h |2 +- kernel/trace/trace_uprobe.c |4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ee41d5700e25..ec20f0b56cfe 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1305,7 +1305,7 @@ static int register_kprobe_event(struct trace_kprobe *tk) init_trace_event_call(tk, call); - if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) + if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) return -ENOMEM; ret = register_trace_event(&call->event); if (!ret) { @@ -1362,7 +1362,7 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, init_trace_event_call(tk, &tk->tp.call); - if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) { + if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) { ret = -ENOMEM; goto error; } diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index cd87490b3492..8d43f377143d 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -504,7 +504,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len, return pos; } -int set_print_fmt(struct trace_probe *tp, bool is_return) +int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return) { int len; char *print_fmt; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index d1b8bd74bf56..3bc43c1ce628 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -266,7 +266,7 @@ extern void traceprobe_free_probe_arg(struct probe_arg *arg); extern int traceprobe_split_symbol_offset(char *symbol, long *offset); -extern int set_print_fmt(struct trace_probe *tp, bool is_return); +extern int traceprobe_set_print_fmt(struct trace_probe *tp, bool is_return); #ifdef CONFIG_PERF_EVENTS extern struct trace_event_call * diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index de4f91bb313a..fafd48310823 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -1314,7 +1314,7 @@ static int register_uprobe_event(struct trace_uprobe *tu) init_trace_event_call(tu, call); - if (set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) + if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) return -ENOMEM; ret = register_trace_event(&call->event); @@ -1388,7 +1388,7 @@ create_local_trace_uprobe(char *name, unsigned long offs, bool is_return) tu->filename = kstrdup(name, GFP_KERNEL); init_trace_event_call(tu, &tu->tp.call); - if (set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) { + if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) { ret = -ENOMEM; goto error; }
Re: [PATCH 05/10] dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
Hi Rob, On Mon, Feb 19, 2018 at 02:35:23PM -0600, Rob Herring wrote: > On Sun, Feb 18, 2018 at 02:14:28AM +0530, Manivannan Sadhasivam wrote: > > Add gpio nodes for Actions Semi S900 SoC. > > > > Signed-off-by: Manivannan Sadhasivam > > --- > > .../devicetree/bindings/gpio/actions,owl-gpio.txt | 15 > > +++ > > 1 file changed, 15 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt > > > > diff --git a/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt > > b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt > > new file mode 100644 > > index ..4cd4cb7bfd1b > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/gpio/actions,owl-gpio.txt > > @@ -0,0 +1,15 @@ > > +* Actions Semi OWL GPIO controller bindings > > + > > +- compatible : Should be "actions,s900-gpio" > > +- reg : Address and range of the GPIO controller registers. > > +- gpio-controller : Marks the device node as a GPIO controller. > > +- #gpio-cells : Should be <2>. The first cell is the gpio number and > > +the second cell is used to specify optional parameters. > > Doesn't do interrupts? > Interrupt support will be added once this base driver gets in. One step at a time ;-) Thanks, Mani > > + > > +Example: > > + gpio: gpio@e01b { > > + compatible = "actions,s900-gpio"; > > + reg = <0x0 0xe01b 0x0 0x1000>; > > + gpio-controller; > > + #gpio-cells = <2>; > > + }; > > -- > > 2.14.1 > >
Re: [PATCH] floppy: Don't print kernel addresses to log in show_floppy
On Wed, Feb 21, 2018 at 12:54 AM, Brian Belleville wrote: > Outputting kernel addresses will reveal the locations of kernel code > and data. Change the cases in show_floppy that print > fd_timer.work.func and fd_timeout.work.func to use the %pf format > specifier, which will print the symbol name, like what is done for the > other function pointers printed by show_floppy. No longer output the > value of cont. The variable cont is a pointer that can hold the > address of kernel global variables. Perhaps you missed %px introduction and hashing pointers otherwise. OTOH I don't give a crap about floppy. -- With Best Regards, Andy Shevchenko
[PATCH v2 07/17] tracing: probeevent: Introduce new argument fetching code
Replace {k,u}probe event argument fetching framework with switch-case based. Currently that is implemented with structures, macros and chain of function-pointers, which is more complicated than necessary and may get a performance penalty by retpoline. This simplify that with an array of "fetch_insn" (opcode and oprands), and make process_fetch_insn() just interprets it. No function pointers are used. Signed-off-by: Masami Hiramatsu --- Changes in v2: - Allow $comm:string. --- kernel/trace/trace_kprobe.c | 314 +++- kernel/trace/trace_probe.c | 441 --- kernel/trace/trace_probe.h | 232 - kernel/trace/trace_probe_tmpl.h | 120 +++ kernel/trace/trace_uprobe.c | 150 +++-- 5 files changed, 517 insertions(+), 740 deletions(-) create mode 100644 kernel/trace/trace_probe_tmpl.h diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index a96328dfc012..5dd2d470cc7e 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -24,6 +24,7 @@ #include #include "trace_probe.h" +#include "trace_probe_tmpl.h" #define KPROBE_EVENT_SYSTEM "kprobes" #define KRETPROBE_MAXACTIVE_MAX 4096 @@ -121,184 +122,6 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); static int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs); -/* Memory fetching by symbol */ -struct symbol_cache { - char*symbol; - longoffset; - unsigned long addr; -}; - -unsigned long update_symbol_cache(struct symbol_cache *sc) -{ - sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol); - - if (sc->addr) - sc->addr += sc->offset; - - return sc->addr; -} - -void free_symbol_cache(struct symbol_cache *sc) -{ - kfree(sc->symbol); - kfree(sc); -} - -struct symbol_cache *alloc_symbol_cache(const char *sym, long offset) -{ - struct symbol_cache *sc; - - if (!sym || strlen(sym) == 0) - return NULL; - - sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL); - if (!sc) - return NULL; - - sc->symbol = kstrdup(sym, GFP_KERNEL); - if (!sc->symbol) { - kfree(sc); - return NULL; - } - sc->offset = offset; - update_symbol_cache(sc); - - return sc; -} - -/* - * Kprobes-specific fetch functions - */ -#define DEFINE_FETCH_stack(type) \ -static void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs, \ - void *offset, void *dest) \ -{ \ - *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \ - (unsigned int)((unsigned long)offset)); \ -} \ -NOKPROBE_SYMBOL(FETCH_FUNC_NAME(stack, type)); - -DEFINE_BASIC_FETCH_FUNCS(stack) -/* No string on the stack entry */ -#define fetch_stack_string NULL -#define fetch_stack_string_sizeNULL - -#define DEFINE_FETCH_memory(type) \ -static void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs, \ - void *addr, void *dest) \ -{ \ - type retval;\ - if (probe_kernel_address(addr, retval)) \ - *(type *)dest = 0; \ - else\ - *(type *)dest = retval; \ -} \ -NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, type)); - -DEFINE_BASIC_FETCH_FUNCS(memory) -/* - * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max - * length and relative data location. - */ -static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, - void *addr, void *dest) -{ - int maxlen = get_rloc_len(*(u32 *)dest); - u8 *dst = get_rloc_data(dest); - long ret; - - if (!maxlen) - return; - - /* -* Try to get string again, since the string can be changed while -* probing. -*/ - ret = strncpy_from_unsafe(dst, addr, maxlen); - - if (ret < 0) { /* Failed to fetch string */ - dst[0] = '\0'; - *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); - } else { - *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest)); - } -} -NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string)); - -/* Ret
[PATCH v2 06/17] tracing: probeevent: Remove NOKPROBE_SYMBOL from print functions
Remove unneeded NOKPROBE_SYMBOL from print functions since the print functions are only used when printing out the trace data, and not from kprobe handler. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_probe.c |4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 4f5447cec44a..37bdd56b4988 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -43,8 +43,7 @@ int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, void *data, void *ent)\ trace_seq_printf(s, fmt, *(type *)data);\ return !trace_seq_has_overflowed(s);\ } \ -const char PRINT_TYPE_FMT_NAME(tname)[] = fmt; \ -NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(tname)); +const char PRINT_TYPE_FMT_NAME(tname)[] = fmt; DEFINE_BASIC_PRINT_TYPE_FUNC(u8, u8, "%u") DEFINE_BASIC_PRINT_TYPE_FUNC(u16, u16, "%u") @@ -71,7 +70,6 @@ int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent) (const char *)get_loc_data(data, ent)); return !trace_seq_has_overflowed(s); } -NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string)); const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
Re: [PATCH 04/10] pinctrl: actions: Add Actions S900 pinctrl driver
Hi Philippe, On Tue, Feb 20, 2018 at 08:53:22AM +0100, Philippe Ombredanne wrote: > Dear Manivannan, > > On Sat, Feb 17, 2018 at 9:44 PM, Manivannan Sadhasivam > wrote: > > Add pinctrl driver for Actions Semi S900 SoC. The driver supports > > pinctrl, pinmux and pinconf functionalities through a range of registers > > common to both gpio driver and pinctrl driver. > > > > Pinmux functionality is available only for the pin groups while the > > pinconf functionality is available for both pin groups and individual > > pins. > > > > Signed-off-by: Manivannan Sadhasivam > > > > > > > --- /dev/null > > +++ b/drivers/pinctrl/actions/pinctrl-s900.c > > @@ -0,0 +1,2536 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > > > > +MODULE_LICENSE("GPL v2"); > > This does not match your license above. Per module.h "GPL v2" means > GPL-2.0 where you license above GPL-2.0+ means or later > Should be MODULE_LICENSE("GPL"). Will get it fixed in next revision. Thanks, Mani > -- > Cordially > Philippe Ombredanne
[PATCH v2 05/17] tracing: probeevent: Cleanup argument field definition
Cleanup event argument definition code in one place for maintenancability. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c | 32 kernel/trace/trace_probe.c | 21 + kernel/trace/trace_probe.h |2 ++ kernel/trace/trace_uprobe.c | 15 ++- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 59882393fc1b..a96328dfc012 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1146,49 +1146,25 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, static int kprobe_event_define_fields(struct trace_event_call *event_call) { - int ret, i; + int ret; struct kprobe_trace_entry_head field; struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data; DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); - /* Set argument names as fields */ - for (i = 0; i < tk->tp.nr_args; i++) { - struct probe_arg *parg = &tk->tp.args[i]; - ret = trace_define_field(event_call, parg->type->fmttype, -parg->name, -sizeof(field) + parg->offset, -parg->type->size, -parg->type->is_signed, -FILTER_OTHER); - if (ret) - return ret; - } - return 0; + return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp); } static int kretprobe_event_define_fields(struct trace_event_call *event_call) { - int ret, i; + int ret; struct kretprobe_trace_entry_head field; struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data; DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0); DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); - /* Set argument names as fields */ - for (i = 0; i < tk->tp.nr_args; i++) { - struct probe_arg *parg = &tk->tp.args[i]; - ret = trace_define_field(event_call, parg->type->fmttype, -parg->name, -sizeof(field) + parg->offset, -parg->type->size, -parg->type->is_signed, -FILTER_OTHER); - if (ret) - return ret; - } - return 0; + return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp); } #ifdef CONFIG_PERF_EVENTS diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 59b0f76fb4a5..4f5447cec44a 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -682,3 +682,24 @@ int set_print_fmt(struct trace_probe *tp, bool is_return) return 0; } + +int traceprobe_define_arg_fields(struct trace_event_call *event_call, +size_t offset, struct trace_probe *tp) +{ + int ret, i; + + /* Set argument names as fields */ + for (i = 0; i < tp->nr_args; i++) { + struct probe_arg *parg = &tp->args[i]; + + ret = trace_define_field(event_call, parg->type->fmttype, +parg->name, +offset + parg->offset, +parg->type->size, +parg->type->is_signed, +FILTER_OTHER); + if (ret) + return ret; + } + return 0; +} diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 0c8e66f9c855..de928052926b 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -440,3 +440,5 @@ extern struct trace_event_call * create_local_trace_uprobe(char *name, unsigned long offs, bool is_return); extern void destroy_local_trace_uprobe(struct trace_event_call *event_call); #endif +extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, + size_t offset, struct trace_probe *tp); diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 4c006a693663..887da2bb63aa 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -982,7 +982,7 @@ probe_event_disable(struct trace_uprobe *tu, struct trace_event_file *file) static int uprobe_event_define_fields(struct trace_event_call *event_call) { - int ret, i, size; + int ret, size; struct uprobe_trace_entry_head field; struct trace_uprobe *tu = event_call->data; @@ -994,19 +994,8 @@ static int uprobe_event_define_fields(struct trace_event_call *event_call) DEFINE_FIELD(unsig
[PATCH v2 04/17] tracing: probeevent: Cleanup print argument functions
Current print argument functions prints the argument name too. It is not good for printing out multiple values for one argument. This change it to just print out the value. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c | 20 ++-- kernel/trace/trace_probe.c | 12 +--- kernel/trace/trace_probe.h | 19 --- kernel/trace/trace_uprobe.c |9 ++--- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index dab4a5b54269..59882393fc1b 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1090,8 +1090,6 @@ print_kprobe_event(struct trace_iterator *iter, int flags, struct kprobe_trace_entry_head *field; struct trace_seq *s = &iter->seq; struct trace_probe *tp; - u8 *data; - int i; field = (struct kprobe_trace_entry_head *)iter->ent; tp = container_of(event, struct trace_probe, call.event); @@ -1103,11 +1101,9 @@ print_kprobe_event(struct trace_iterator *iter, int flags, trace_seq_putc(s, ')'); - data = (u8 *)&field[1]; - for (i = 0; i < tp->nr_args; i++) - if (!tp->args[i].type->print(s, tp->args[i].name, -data + tp->args[i].offset, field)) - goto out; + if (print_probe_args(s, tp->args, tp->nr_args, +(u8 *)&field[1], field) < 0) + goto out; trace_seq_putc(s, '\n'); out: @@ -1121,8 +1117,6 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, struct kretprobe_trace_entry_head *field; struct trace_seq *s = &iter->seq; struct trace_probe *tp; - u8 *data; - int i; field = (struct kretprobe_trace_entry_head *)iter->ent; tp = container_of(event, struct trace_probe, call.event); @@ -1139,11 +1133,9 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, trace_seq_putc(s, ')'); - data = (u8 *)&field[1]; - for (i = 0; i < tp->nr_args; i++) - if (!tp->args[i].type->print(s, tp->args[i].name, -data + tp->args[i].offset, field)) - goto out; + if (print_probe_args(s, tp->args, tp->nr_args, +(u8 *)&field[1], field) < 0) + goto out; trace_seq_putc(s, '\n'); diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 3e291a754862..59b0f76fb4a5 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -38,10 +38,9 @@ const char *reserved_field_names[] = { /* Printing in basic type function template */ #define DEFINE_BASIC_PRINT_TYPE_FUNC(tname, type, fmt) \ -int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, const char *name, \ - void *data, void *ent) \ +int PRINT_TYPE_FUNC_NAME(tname)(struct trace_seq *s, void *data, void *ent)\ { \ - trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ + trace_seq_printf(s, fmt, *(type *)data);\ return !trace_seq_has_overflowed(s);\ } \ const char PRINT_TYPE_FMT_NAME(tname)[] = fmt; \ @@ -61,15 +60,14 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(x32, u32, "0x%x") DEFINE_BASIC_PRINT_TYPE_FUNC(x64, u64, "0x%Lx") /* Print type function for string type */ -int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name, -void *data, void *ent) +int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, void *data, void *ent) { int len = *(u32 *)data >> 16; if (!len) - trace_seq_printf(s, " %s=(fault)", name); + trace_seq_puts(s, "(fault)"); else - trace_seq_printf(s, " %s=\"%s\"", name, + trace_seq_printf(s, "\"%s\"", (const char *)get_loc_data(data, ent)); return !trace_seq_has_overflowed(s); } diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 75daff22ccea..0c8e66f9c855 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -94,7 +94,7 @@ static nokprobe_inline void *get_loc_data(u32 *dl, void *ent) /* Data fetch function type */ typedefvoid (*fetch_func_t)(struct pt_regs *, void *, void *); /* Printing function type */ -typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *, void *); +typedef int (*print_type_func_t)(struct trace_seq *, void *, void *); /* Fetch types */ enum { @@ -136,8 +136,7 @@ typedef u32 string_size; /* Printing in basic type function template */ #define DECLARE_BASIC_PRINT_TYPE_FU
Re: [PATCH 08/10] gpio: Add gpio driver for Actions OWL S900 SoC
Hi Philippe, On Tue, Feb 20, 2018 at 08:55:57AM +0100, Philippe Ombredanne wrote: > Manivannan, > > On Sat, Feb 17, 2018 at 9:44 PM, Manivannan Sadhasivam > wrote: > > Add gpio driver for Actions Semi OWL family S900 SoC. Set of registers > > controlling the gpio shares the same register range with pinctrl block. > > > > GPIO registers are organized as 6 banks and each bank controls the > > maximum of 32 gpios. > > > > Signed-off-by: Manivannan Sadhasivam > > > > > --- /dev/null > > +++ b/drivers/gpio/gpio-owl.c > > @@ -0,0 +1,258 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > > > > +MODULE_LICENSE("GPL v2"); > > Please sync this with your SPDX id above. nodule.h has the doc on the > meaning of MODULE_LICENSE macros. > Here you have stated a combo of GPL-2.0 and GPL-2.0 or later > Sorry. It should be MODULE_LICENSE("GPL"). Will get it fixed in next revision. Thanks, Mani > -- > Cordially > Philippe Ombredanne
[PATCH v2 03/17] selftests: ftrace: Add a testcase for string type with kprobe_event
Add a testcase for string type with kprobe event. This tests good/bad syntax combinations and also the traced data is correct in several way. Signed-off-by: Masami Hiramatsu --- .../ftrace/test.d/kprobe/kprobe_args_string.tc | 46 1 file changed, 46 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc new file mode 100644 index ..5ba73035e1d9 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc @@ -0,0 +1,46 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Kprobe event string type argument + +[ -f kprobe_events ] || exit_unsupported # this is configurable + +echo 0 > events/enable +echo > kprobe_events + +case `uname -m` in +x86_64) + ARG2=%si + OFFS=8 +;; +i[3456]86) + ARG2=%cx + OFFS=4 +;; +aarch64) + ARG2=%x1 + OFFS=8 +;; +arm*) + ARG2=%r1 + OFFS=4 +;; +*) + echo "Please implement other architecture here" + exit_untested +esac + +: "Test get argument (1)" +echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string" > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo test >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1=\"test\"" + +echo 0 > events/kprobes/testprobe/enable +: "Test get argument (2)" +echo "p:testprobe create_trace_kprobe arg1=+0(+0(${ARG2})):string arg2=+0(+${OFFS}(${ARG2})):string" > kprobe_events +echo 1 > events/kprobes/testprobe/enable +! echo test1 test2 >> kprobe_events +tail -n 1 trace | grep -qe "testprobe.* arg1=\"test1\" arg2=\"test2\"" + +echo 0 > events/enable +echo > kprobe_events
[PATCH V2] powerpc/powernv : Add support to enable sensor groups
Adds support to enable/disable a sensor group. This can be used to select the sensor groups that needs to be copied to main memory by OCC. Sensor groups like power, temperature, current, voltage, frequency, utilization can be enabled/disabled at runtime. Signed-off-by: Shilpasri G Bhat --- Changes from V1: - Rebase on master - Add documentation .../ABI/testing/sysfs-firmware-opal-sensor-groups | 34 ++ arch/powerpc/include/asm/opal-api.h| 4 +- arch/powerpc/include/asm/opal.h| 1 + .../powerpc/platforms/powernv/opal-sensor-groups.c | 123 - arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + 5 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-firmware-opal-sensor-groups diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-sensor-groups b/Documentation/ABI/testing/sysfs-firmware-opal-sensor-groups new file mode 100644 index 000..81081de --- /dev/null +++ b/Documentation/ABI/testing/sysfs-firmware-opal-sensor-groups @@ -0,0 +1,34 @@ +What: /sys/firmware/opal/sensor_groups +Date: January 2018 +Contact: Linux for PowerPC mailing list +Description: Sensor groups directory for POWER9 powernv servers + + Each folder in this directory contains a sensor group + which are classified based on type of the sensor + like power, temperature, frequency, current, etc. They + can also indicate the group of sensors belonging to + different owners like CSM, Profiler, Job-Scheduler + +What: /sys/firmware/opal/sensor_groups//clear +Date: Januaury 2018 +Contact: Linux for PowerPC mailing list +Description: Sysfs file to clear the min-max of all the sensors + belonging to the group. + + Writing 1 to this file will clear the minimum and + maximum values of all the sensors in the group. The + min-max of a sensor is the historical minimum and + maximum value of the sensor cached by OCC. + +What: /sys/firmware/opal/sensor_groups//enable +Date: Januaury 2018 +Contact: Linux for PowerPC mailing list +Description: Sysfs file to enable/disable the sensor-group + + Writing 0 value to this file will disable the copying + of the sensor-group to main memory by OCC. And writing + 1 to this file will enable the sensor-group copying. + By default all the sensor-groups are enabled and will + be copied to main memory. This file can be used to + increase the update frequency of selective + sensor-groups. diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index 94bd1bf..b6bbbd8 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -204,7 +204,9 @@ #define OPAL_NPU_SPA_SETUP 159 #define OPAL_NPU_SPA_CLEAR_CACHE 160 #define OPAL_NPU_TL_SET161 -#define OPAL_LAST 161 +#define OPAL_SENSOR_READ_U64 162 +#define OPAL_SENSOR_GROUP_ENABLE 163 +#define OPAL_LAST 163 /* Device tree flags */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 12e70fb..e708c41 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -286,6 +286,7 @@ int64_t opal_imc_counters_init(uint32_t type, uint64_t address, int opal_get_power_shift_ratio(u32 handle, int token, u32 *psr); int opal_set_power_shift_ratio(u32 handle, int token, u32 psr); int opal_sensor_group_clear(u32 group_hndl, int token); +int opal_sensor_group_enable(u32 group_hndl, int token, bool enable); s64 opal_signal_system_reset(s32 cpu); diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c b/arch/powerpc/platforms/powernv/opal-sensor-groups.c index 7e5a235..1a3359d 100644 --- a/arch/powerpc/platforms/powernv/opal-sensor-groups.c +++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c @@ -24,6 +24,8 @@ struct sg_attr { u32 handle; struct kobj_attribute attr; + u32 opal_no; + int enable; }; static struct sensor_group { @@ -32,34 +34,44 @@ struct sg_attr { struct sg_attr *sgattrs; } *sgs; -static ssize_t sg_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) +static int sensor_group_clear(u32 handle) { - struct sg_attr *sattr = container_of(attr, struct sg_attr, attr); struct opal_msg msg; - u32 data; - int ret, token; - - ret = kstrtoint(buf, 0, &data); - if (ret) - return ret; - - if (data != 1) - return -EINVAL; + int token, ret; token = opal_async_get
[PATCH v2 02/17] selftests: ftrace: Add probe event argument syntax testcase
Add a testcase for probe event argument syntax which ensures the kprobe_events interface correctly parses given event arguments. Signed-off-by: Masami Hiramatsu --- .../ftrace/test.d/kprobe/kprobe_args_syntax.tc | 97 1 file changed, 97 insertions(+) create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc new file mode 100644 index ..231bcd2c4eb5 --- /dev/null +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc @@ -0,0 +1,97 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# description: Kprobe event argument syntax + +[ -f kprobe_events ] || exit_unsupported # this is configurable + +grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue + +echo 0 > events/enable +echo > kprobe_events + +PROBEFUNC="vfs_read" +GOODREG= +BADREG= +GOODSYM="_sdata" +if ! grep -qw ${GOODSYM} /proc/kallsyms ; then + GOODSYM=$PROBEFUNC +fi +BADSYM="deaqswdefr" +SYMADDR=0x`grep -w ${GOODSYM} /proc/kallsyms | cut -f 1 -d " "` +GOODTYPE="x16" +BADTYPE="y16" + +case `uname -m` in +x86_64|i[3456]86) + GOODREG=%ax + BADREG=%ex +;; +aarch64) + GOODREG=%x0 + BADREG=%ax +;; +arm*) + GOODREG=%r0 + BADREG=%ax +;; +esac + +test_goodarg() # Good-args +{ + while [ "$1" ]; do +echo "p ${PROBEFUNC} $1" > kprobe_events +shift 1 + done; +} + +test_badarg() # Bad-args +{ + while [ "$1" ]; do +! echo "p ${PROBEFUNC} $1" > kprobe_events +shift 1 + done; +} + +echo > kprobe_events + +: "Register access" +test_goodarg ${GOODREG} +test_badarg ${BADREG} + +: "Symbol access" +test_goodarg "@${GOODSYM}" "@${SYMADDR}" "@${GOODSYM}+10" "@${GOODSYM}-10" +test_badarg "@" "@${BADSYM}" "@${GOODSYM}*10" "@${GOODSYM}/10" \ + "@${GOODSYM}%10" "@${GOODSYM}&10" "@${GOODSYM}|10" + +: "Stack access" +test_goodarg "\$stack" "\$stack0" "\$stack1" +test_badarg "\$stackp" "\$stack0+10" "\$stack1-10" + +: "Retval access" +echo "r ${PROBEFUNC} \$retval" > kprobe_events +! echo "p ${PROBEFUNC} \$retval" > kprobe_events + +: "Comm access" +test_goodarg "\$comm" + +: "Indirect memory access" +test_goodarg "+0(${GOODREG})" "-0(${GOODREG})" "+10(\$stack)" \ + "+0(\$stack1)" "+10(@${GOODSYM}-10)" "+0(+10(+20(\$stack)))" +test_badarg "+(${GOODREG})" "(${GOODREG}+10)" "-(${GOODREG})" "(${GOODREG})" \ + "+10(\$comm)" "+0(${GOODREG})+10" + +: "Name assignment" +test_goodarg "varname=${GOODREG}" +test_badarg "varname=varname2=${GOODREG}" + +: "Type syntax" +test_goodarg "${GOODREG}:${GOODTYPE}" +test_badarg "${GOODREG}::${GOODTYPE}" "${GOODREG}:${BADTYPE}" \ + "${GOODTYPE}:${GOODREG}" + +: "Combination check" + +test_goodarg "\$comm:string" "+0(\$stack):string" +test_badarg "\$comm:x64" "\$stack:string" "${GOODREG}:string" + +echo > kprobe_events
[PATCH v2 01/17] tracing: probeevent: Fix to support minus offset from symbol
In Documentation/trace/kprobetrace.txt, it says @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol) However, the parser doesn't parse minus offset correctly. This fixes the parser to get minus offset correctly. Signed-off-by: Masami Hiramatsu --- kernel/trace/trace_kprobe.c |2 +- kernel/trace/trace_probe.c | 10 +- kernel/trace/trace_probe.h |2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5ce9b8cf7be3..dab4a5b54269 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -754,7 +754,7 @@ static int create_trace_kprobe(int argc, char **argv) /* a symbol specified */ symbol = argv[1]; /* TODO: support .init module functions */ - ret = traceprobe_split_symbol_offset(symbol, &offset); + ret = traceprobe_split_symbol_offset(symbol, (long *)&offset); if (ret) { pr_info("Failed to parse either an address or a symbol.\n"); return ret; diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index d59357308677..3e291a754862 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -320,7 +320,7 @@ static fetch_func_t get_fetch_size_function(const struct fetch_type *type, } /* Split symbol and offset. */ -int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) +int traceprobe_split_symbol_offset(char *symbol, long *offset) { char *tmp; int ret; @@ -328,13 +328,13 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) if (!offset) return -EINVAL; - tmp = strchr(symbol, '+'); + tmp = strpbrk(symbol, "+-"); if (tmp) { - /* skip sign because kstrtoul doesn't accept '+' */ - ret = kstrtoul(tmp + 1, 0, offset); + ret = kstrtoul(tmp + 1, 0, (unsigned long *)offset); if (ret) return ret; - + if (*tmp == '-') + *offset = -(*offset); *tmp = '\0'; } else *offset = 0; diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 0745f895f780..75daff22ccea 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -365,7 +365,7 @@ extern int traceprobe_conflict_field_name(const char *name, extern void traceprobe_update_arg(struct probe_arg *arg); extern void traceprobe_free_probe_arg(struct probe_arg *arg); -extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset); +extern int traceprobe_split_symbol_offset(char *symbol, long *offset); /* Sum up total data length for dynamic arraies (strings) */ static nokprobe_inline int
Re: [PATCH 1/4] drm/atomic: integrate modeset lock with private objects
On Wed, Feb 21, 2018 at 9:49 AM, Ville Syrjälä wrote: > On Wed, Feb 21, 2018 at 09:37:21AM -0500, Rob Clark wrote: >> Follow the same pattern of locking as with other state objects. This >> avoids boilerplate in the driver. > > I'm not sure we really want to do this. What if the driver wants a > custom locking scheme for this state? That seems like something we want to discourage, ie. all the more reason for this patch. There is no reason drivers could not split their global state into multiple private objs's, each with their own lock, for more fine grained locking. That is basically the only valid reason I can think of for "custom locking". (And ofc drivers could add there own locks in addition to what is done by core, but I'd rather look at that on a case by case basis, rather than it being part of the boilerplate in each driver.) BR, -R >> >> Signed-off-by: Rob Clark >> --- >> drivers/gpu/drm/drm_atomic.c | 9 - >> include/drm/drm_atomic.h | 5 + >> 2 files changed, 13 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c >> index fc8c4da409ff..004e621ab307 100644 >> --- a/drivers/gpu/drm/drm_atomic.c >> +++ b/drivers/gpu/drm/drm_atomic.c >> @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj >> *obj, >> { >> memset(obj, 0, sizeof(*obj)); >> >> + drm_modeset_lock_init(&obj->lock); >> + >> obj->state = state; >> obj->funcs = funcs; >> } >> @@ -1093,6 +1095,7 @@ void >> drm_atomic_private_obj_fini(struct drm_private_obj *obj) >> { >> obj->funcs->atomic_destroy_state(obj, obj->state); >> + drm_modeset_lock_fini(&obj->lock); >> } >> EXPORT_SYMBOL(drm_atomic_private_obj_fini); >> >> @@ -1113,7 +1116,7 @@ struct drm_private_state * >> drm_atomic_get_private_obj_state(struct drm_atomic_state *state, >>struct drm_private_obj *obj) >> { >> - int index, num_objs, i; >> + int index, num_objs, i, ret; >> size_t size; >> struct __drm_private_objs_state *arr; >> struct drm_private_state *obj_state; >> @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct >> drm_atomic_state *state, >> if (obj == state->private_objs[i].ptr) >> return state->private_objs[i].state; >> >> + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); >> + if (ret) >> + return ERR_PTR(ret); >> + >> num_objs = state->num_private_objs + 1; >> size = sizeof(*state->private_objs) * num_objs; >> arr = krealloc(state->private_objs, size, GFP_KERNEL); >> diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h >> index 09076a625637..9ae53b73c9d2 100644 >> --- a/include/drm/drm_atomic.h >> +++ b/include/drm/drm_atomic.h >> @@ -218,6 +218,11 @@ struct drm_private_state_funcs { >> * &drm_modeset_lock is required to duplicate and update this object's >> state. >> */ >> struct drm_private_obj { >> + /** >> + * @lock: Modeset lock to protect the state object. >> + */ >> + struct drm_modeset_lock lock; >> + >> /** >>* @state: Current atomic state for this driver private object. >>*/ >> -- >> 2.14.3 >> >> ___ >> dri-devel mailing list >> dri-de...@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel > > -- > Ville Syrjälä > Intel OTC
[PATCH v2 00/17] tracing: probeevent: Improve fetcharg features
Hi, This is the 2nd version of the fetch-arg improvement series. This includes variable changes on fetcharg framework like, - Add fetcharg testcases (syntax, argN, symbol, string and array) - Rewrite fetcharg framework with fetch_insn, switch-case based instead of function pointer. - Add "symbol" type support, which shows symbol+offset instead of address value. - Add "$argN" fetcharg, which fetches function parameters. (currently only for x86-64) - Add array type support (including string arrary :) ) , which enables to get fixed length array from probeevents. >From the v1, I've added many fixes and testcases. The 2 biggest change are adding many testcases and support string array. Note that the first 3 patches ([1/17] - [3/17]) can be applied independently, since those are a bugfix and testcase for existing features. The string array type (e.g. +0(%si):string[2]) is a bit different from other array types (like x16[8] etc.). For other types, [1] is equal to (e.g. +0(%di):x32[1] is same as +0(%di):x32.) But "string[1]" is not equal to "string". The string type itself represents "char array", but string array type represents "char * array". So, for example, +0(%di):string[1] is equal to +0(+0(%di)):string. The 1st version is here: https://www.spinics.net/lists/linux-trace/msg00583.html Here are examples: o 'symbol' type # echo 'p vfs_read $stack0:symbol' > kprobe_events # echo 1 > events/kprobes/p_vfs_read_0/enable # tail -n 3 trace sh-729 [007] ...2 105.753637: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=SyS_read+0x42/0x90 tail-736 [000] ...2 105.754904: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=kernel_read+0x2c/0x40 tail-736 [000] ...2 105.754929: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=kernel_read+0x2c/0x40 o $argN # echo 'p vfs_read $arg0 $arg1 $arg2' > kprobe_events # echo 1 > events/kprobes/p_vfs_read_0/enable # tail -n 3 trace sh-726 [007] ...2 134.288973: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x88001d98ec00 arg2=0x7ffeb4330f79 arg3=0x1 tail-731 [000] ...2 134.289987: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x88001d9dd200 arg2=0x88001d8a0a00 arg3=0x80 tail-731 [000] ...2 134.290016: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x88001d9dd200 arg2=0x88001faf4a00 arg3=0x150 o Array type # echo 'p vfs_read +0($stack):x64 +0($stack):x8[8]' > kprobe_events # echo 1 > events/kprobes/p_vfs_read_0/enable # tail -n 3 trace sh-729 [007] ...291.701664: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x811b1252 arg2={0x52,0x12,0x1b,0x81,0xff,0xff,0xff,0xff} tail-734 [000] ...291.702366: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x811b0dec arg2={0xec,0xd,0x1b,0x81,0xff,0xff,0xff,0xff} tail-734 [000] ...291.702386: p_vfs_read_0: (vfs_read+0x0/0x130) arg1=0x811b0dec arg2={0xec,0xd,0x1b,0x81,0xff,0xff,0xff,0xff} # # cat events/kprobes/p_vfs_read_0/format name: p_vfs_read_0 ID: 1069 format: field:unsigned short common_type; offset:0; size:2; signed:0; field:unsigned char common_flags; offset:2; size:1; signed:0; field:unsigned char common_preempt_count; offset:3; size:1; signed:0; field:int common_pid; offset:4; size:4; signed:1; field:unsigned long __probe_ip; offset:8; size:8; signed:0; field:u64 arg1; offset:16; size:0; signed:0; field:u8 arg2[8]; offset:24; size:8; signed:0; print fmt: "(%lx) arg1=0x%Lx arg2={0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}", REC->__probe_ip, REC->arg1, REC->arg2[0], REC->arg2[1], REC->arg2[2], REC->arg2[3], REC->arg2[4], REC->arg2[5], REC->arg2[6], REC->arg2[7] o String Array type # echo "p create_trace_kprobe arg1=+0(%si):string[3]" > kprobe_events # echo test1 test2 test3 >> kprobe_events sh: write error: Invalid argument # echo 'p vfs_read $stack' >> kprobe_events # tail -n 2 trace sh-744 [007] ...1 183.382407: p_create_trace_kprobe_0: (create_trace_kprobe+0x0/0x890) arg1={"test1","test2","test3"} sh-744 [007] ...1 230.487809: p_create_trace_kprobe_0: (create_trace_kprobe+0x0/0x890) arg1={"p","vfs_read","$stack"} Thank you, --- Masami Hiramatsu (17): tracing: probeevent: Fix to support minus offset from symbol selftests: ftrace: Add probe event argument syntax testcase selftests: ftrace: Add a testcase for string type with kprobe_event tracing: probeevent: Cleanup print argument functions tracing: probeevent: Cleanup argument field definition tracing: probeevent: Remove NOKPROBE_SYMBOL from print functions tracing: probeevent: Introduce new argument fetching code tracing: probeevent: Return consumed bytes of dynamic area tracing: probeevent: Append traceprobe_ for exported function tracing: probeevent: Unify fetch_insn
Re: [PATCH] netlink: put module reference if dump start fails
On Wed, Feb 21, 2018 at 6:47 AM, Eric Dumazet wrote: >> This probably should be queued up for stable. > > When was the bug added ? This would help a lot stable teams ... This needs to be backported to 4.16-rc0+, 4.15+, 4.14+, 4.13.14+, and 4.9.63+.
Re: net: hang in unregister_netdevice: waiting for lo to become free
On 20.02.2018 18:26, Neil Horman wrote: On Tue, Feb 20, 2018 at 09:14:41AM +0100, Dmitry Vyukov wrote: On Tue, Feb 20, 2018 at 8:56 AM, Tommi Rantala wrote: On 19.02.2018 20:59, Dmitry Vyukov wrote: Is this meant to be fixed already? I am still seeing this on the latest upstream tree. These two commits are in v4.16-rc1: commit 4a31a6b19f9ddf498c81f5c9b089742b7472a6f8 Author: Tommi Rantala Date: Mon Feb 5 21:48:14 2018 +0200 sctp: fix dst refcnt leak in sctp_v4_get_dst ... Fixes: 410f03831 ("sctp: add routing output fallback") Fixes: 0ca50d12f ("sctp: fix src address selection if using secondary addresses") commit 957d761cf91cdbb175ad7d8f5472336a4d54dbf2 Author: Alexey Kodanev Date: Mon Feb 5 15:10:35 2018 +0300 sctp: fix dst refcnt leak in sctp_v6_get_dst() ... Fixes: dbc2b5e9a09e ("sctp: fix src address selection if using secondary addresses for ipv6") I guess we missed something if it's still reproducible. I can check it later this week, unless someone else beat me to it. Hi Tommi, Hmmm, I can't claim that it's exactly the same bug. Perhaps it's another one then. But I am still seeing these: [ 58.799130] unregister_netdevice: waiting for lo to become free. Usage count = 4 [ 60.847138] unregister_netdevice: waiting for lo to become free. Usage count = 4 [ 62.895093] unregister_netdevice: waiting for lo to become free. Usage count = 4 [ 64.943103] unregister_netdevice: waiting for lo to become free. Usage count = 4 on upstream tree pulled ~12 hours ago. Can you write a systemtap script to probe dev_hold, and dev_put, printing out a backtrace if the device name matches "lo". That should tell us definitively if the problem is in the same location or not Hi Dmitry, I tested with the reproducer and the kernel .config file that you sent in the first email in this thread: With 4.16-rc2 unable to reproduce. With 4.15-rc9 bug reproducible, and I get "unregister_netdevice: waiting for lo to become free. Usage count = 3" With 4.15-rc9 and Alexey's "sctp: fix dst refcnt leak in sctp_v6_get_dst()" cherry-picked on top, unable to reproduce. Is syzkaller doing something else now to trigger the bug...? Can you still trigger the bug with the same reproducer? Tommi
Re: [PATCH v2 1/2] KVM: x86: Add a framework for supporting MSR-based features
On 2/21/2018 8:47 AM, Tom Lendacky wrote: > On 2/21/2018 8:32 AM, Paolo Bonzini wrote: >> On 21/02/2018 15:15, Tom Lendacky wrote: >>> On 2/21/2018 5:41 AM, Paolo Bonzini wrote: On 16/02/2018 00:12, Tom Lendacky wrote: > +static u32 msr_based_features[] = { > +}; > + > +static unsigned int num_msr_based_features = > ARRAY_SIZE(msr_based_features); > + > bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) > { > if (efer & efer_reserved_bits) > @@ -2785,6 +2794,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, > long ext) > case KVM_CAP_SET_BOOT_CPU_ID: > case KVM_CAP_SPLIT_IRQCHIP: > case KVM_CAP_IMMEDIATE_EXIT: > + case KVM_CAP_GET_MSR_FEATURES: > r = 1; > break; > case KVM_CAP_ADJUST_CLOCK: > @@ -4410,6 +4420,47 @@ long kvm_arch_vm_ioctl(struct file *filp, > r = kvm_x86_ops->mem_enc_unreg_region(kvm, ®ion); > break; > } > + case KVM_GET_MSR_INDEX_LIST: { > + struct kvm_msr_list __user *user_msr_list = argp; > + struct kvm_msr_list msr_list; > + unsigned int n; > + > + r = -EFAULT; > + if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list))) > + goto out; > + n = msr_list.nmsrs; > + msr_list.nmsrs = num_msr_based_features; > + if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list))) > + goto out; > + r = -E2BIG; > + if (n < msr_list.nmsrs) > + goto out; > + r = -EFAULT; > + if (copy_to_user(user_msr_list->indices, &msr_based_features, > + num_msr_based_features * sizeof(u32))) > + goto out; > + r = 0; > + break; I think it's better to have some logic in kvm_init_msr_list, to filter the MSR list based on whatever MSRs the backend provides. >>> >>> Ok, that's what I had originally and then you said to just return the full >>> list and let KVM_GET_MSR return a 0 or 1 if it was supported. I can switch >>> it back. >> >> Hmm, I cannot find this remark (I would have been very confused, so I >> tried to look for it). I commented on removing kvm_valid_msr_feature, >> but not kvm_init_msr_list. > > I think this is the reply that sent me off on that track: > https://marc.info/?l=linux-kernel&m=151862648123153&w=2 > > I'll make it consistent with the other MSR-related items and initialize > the list in kvm_init_msr_list(). I'll change the signature of the > msr_feature() kvm_x86_ops callback to take an index and optionally return > a data value so it can be used to check for support when building the > list and return a value when needed. Hmm, actually I'll just leave the signature alone and pass in a local kvm_msr_entry struct variable for the call when initializing the list. Thanks, Tom > > Thanks, > Tom > >> > + } > + case KVM_GET_MSR: { It's not that the API isn't usable, KVM_GET_MSR is fine for what we need here (it's not a fast path), but it's a bit confusing to have KVM_GET_MSR and KVM_GET_MSRS. I see two possibilities: 1) reuse KVM_GET_MSRS as in the previous version. It's okay to cut-and-paste code from msr_io. >>> >>> If I go back to trimming the list based on support, then KVM_GET_MSRS can >>> be used. >> >> No problem, renaming is enough---I should have made a better suggestion >> in the previous review. >> >> Paolo >>
Re: [PATCH 05/10] hwmon: generic-pwm-tachometer: Add generic PWM based tachometer
On 02/20/2018 10:58 PM, Rajkumar Rampelli wrote: Add generic PWM based tachometer driver via HWMON interface to report the RPM of motor. This drivers get the period/duty cycle from PWM IP which captures the motor PWM output. This driver implements a simple interface for monitoring the speed of a fan and exposes it in roatations per minute (RPM) to the user space by using the hwmon's sysfs interface Signed-off-by: Rajkumar Rampelli --- Documentation/hwmon/generic-pwm-tachometer | 17 + drivers/hwmon/Kconfig | 10 +++ drivers/hwmon/Makefile | 1 + drivers/hwmon/generic-pwm-tachometer.c | 112 + 4 files changed, 140 insertions(+) create mode 100644 Documentation/hwmon/generic-pwm-tachometer create mode 100644 drivers/hwmon/generic-pwm-tachometer.c diff --git a/Documentation/hwmon/generic-pwm-tachometer b/Documentation/hwmon/generic-pwm-tachometer new file mode 100644 index 000..e0713ee --- /dev/null +++ b/Documentation/hwmon/generic-pwm-tachometer @@ -0,0 +1,17 @@ +Kernel driver generic-pwm-tachometer + + +This driver enables the use of a PWM module to monitor a fan. It uses the +generic PWM interface and can be used on SoCs as along as the SoC supports +Tachometer controller that moniors the Fan speed in periods. + +Author: Rajkumar Rampelli + +Description +--- + +The driver implements a simple interface for monitoring the Fan speed using +PWM module and Tachometer controller. It requests period value through PWM +capture interface to Tachometer and measures the Rotations per minute using +received period value. It exposes the Fan speed in RPM to the user space by +using the hwmon's sysfs interface. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ef23553..8912dcb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1878,6 +1878,16 @@ config SENSORS_XGENE If you say yes here you get support for the temperature and power sensors for APM X-Gene SoC. +config GENERIC_PWM_TACHOMETER + tristate "Generic PWM based tachometer driver" + depends on PWM + help + Enables a driver to use PWM signal from motor to use + for measuring the motor speed. The RPM is captured by + PWM modules which has PWM capture capability and this + drivers reads the captured data from PWM IP to convert + it to speed in RPM. + if ACPI comment "ACPI drivers" diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index f814b4a..9dcc374 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -175,6 +175,7 @@ obj-$(CONFIG_SENSORS_WM8350)+= wm8350-hwmon.o obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o obj-$(CONFIG_PMBUS) += pmbus/ +obj-$(CONFIG_GENERIC_PWM_TACHOMETER) += generic-pwm-tachometer.o ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG diff --git a/drivers/hwmon/generic-pwm-tachometer.c b/drivers/hwmon/generic-pwm-tachometer.c new file mode 100644 index 000..9354d43 --- /dev/null +++ b/drivers/hwmon/generic-pwm-tachometer.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include + +struct pwm_hwmon_tach { + struct device *dev; + struct pwm_device *pwm; + struct device *hwmon; +}; + +static ssize_t show_rpm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_hwmon_tach *ptt = dev_get_drvdata(dev); + struct pwm_device *pwm = ptt->pwm; + struct pwm_capture result; + int err; + unsigned int rpm = 0; + + err = pwm_capture(pwm, &result, 0); + if (err < 0) { + dev_err(ptt->dev, "Failed to capture PWM: %d\n", err); + return err; + } + + if (result.period) + rpm = DIV_ROUND_CLOSEST_ULL(60ULL * NSEC_PER_SEC, + result.period); + + return sprintf(buf, "%u\n", rpm); +} + +static SENSOR_DEVICE_ATTR(rpm, 0444, show_rpm, NULL, 0); + +static struct attribute *pwm_tach_attrs[] = { + &sensor_dev_attr_rpm.dev_attr.attr, + NULL, +}; "rpm" is not a standard hwmon sysfs attribute. If you don't provide a single standard hwmon sysfs attribute, having a hwmon driver is pointless. + +ATTRIBUTE_GROUPS(pwm_tach); + +static int pwm_tach_probe(struct p
[PATCH 3/3] platform/chrome: mfd/cros_ec_dev: Add sysfs entry to set keyboard wake lid angle
From: Gwendal Grignou This adds a sysfs attribute (/sys/class/chromeos/cros_ec/kb_wake_angle) used to set and get the keyboard wake lid angle. This attribute is present only if 2 accelerometers are controlled by the EC. This patch also moves the cros_ec features check before the device is added so the features map obtained from the EC is ready on time. Signed-off-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra --- drivers/mfd/cros_ec_dev.c | 19 drivers/platform/chrome/cros_ec_sysfs.c | 83 + include/linux/mfd/cros_ec.h | 1 + 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 9d4b74404f49..48eac38a7d62 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -485,15 +485,6 @@ static int ec_device_probe(struct platform_device *pdev) goto failed; } - retval = cdev_device_add(&ec->cdev, &ec->class_dev); - if (retval) { - dev_err(dev, "cdev_device_add failed => %d\n", retval); - goto failed; - } - - if (cros_ec_debugfs_init(ec)) - dev_warn(dev, "failed to create debugfs directory\n"); - /* check whether this EC is a sensor hub. */ if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) cros_ec_sensors_register(ec); @@ -514,6 +505,16 @@ static int ec_device_probe(struct platform_device *pdev) /* Take control of the lightbar from the EC. */ lb_manual_suspend_ctrl(ec, 1); + /* We can now add the sysfs class, we know which parameter to show */ + retval = cdev_device_add(&ec->cdev, &ec->class_dev); + if (retval) { + dev_err(dev, "cdev_device_add failed => %d\n", retval); + goto failed; + } + + if (cros_ec_debugfs_init(ec)) + dev_warn(dev, "failed to create debugfs directory\n"); + return 0; failed: diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index c03621e523a3..ae50a5342d58 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -259,21 +259,104 @@ static ssize_t show_ec_flashinfo(struct device *dev, return ret; } +/* Keyboard wake angle control */ +static ssize_t show_kb_wake_angle(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ec_response_motion_sense *resp; + struct ec_params_motion_sense *param; + struct cros_ec_command *msg; + int ret; + struct cros_ec_dev *ec = container_of( + dev, struct cros_ec_dev, class_dev); + + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + param = (struct ec_params_motion_sense *)msg->data; + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; + msg->version = 2; + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; + param->kb_wake_angle.data = EC_MOTION_SENSE_NO_VALUE; + msg->outsize = sizeof(*param); + msg->insize = sizeof(*resp); + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); + if (ret < 0) + goto exit; + resp = (struct ec_response_motion_sense *)msg->data; + ret = scnprintf(buf, PAGE_SIZE, "%d\n", + resp->kb_wake_angle.ret); +exit: + kfree(msg); + return ret; +} + +static ssize_t store_kb_wake_angle(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ec_params_motion_sense *param; + struct cros_ec_command *msg; + int ret; + struct cros_ec_dev *ec = container_of( + dev, struct cros_ec_dev, class_dev); + u16 angle; + + ret = kstrtou16(buf, 0, &angle); + if (ret) + return ret; + + msg = kmalloc(sizeof(*msg) + EC_HOST_PARAM_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + param = (struct ec_params_motion_sense *)msg->data; + msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset; + msg->version = 2; + param->cmd = MOTIONSENSE_CMD_KB_WAKE_ANGLE; + param->kb_wake_angle.data = angle; + msg->outsize = sizeof(*param); + msg->insize = sizeof(struct ec_response_motion_sense); + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); + kfree(msg); + if (ret < 0) + return ret; + return count; +} + /* Module initialization */ static DEVICE_ATTR(reboot, S_IWUSR | S_IRUGO, show_ec_reboot, store_ec_reboot); static DEVICE_ATTR(version, S_IRUGO, show_ec_version, NULL); static DEVICE_ATTR(flashinfo, S_IRUGO, show_ec_flashinfo, NULL); +static DEVICE_ATTR(kb_wake_angle, S_IWUSR | S_IRUGO, show_kb_wake_angle, +
[PATCH 1/3] platform/chrome: cros_ec_sysfs: Modify error handling
From: Gwendal Grignou When accessing a sysfs attribute, if the EC command fails, -EPROTO is now returned instead of an error message as it is unlikely an app is parsing the error message to do something meaningful. Also, this patch makes use of cros_ec_cmd_xfer_status() instead of cros_ec_cmd_xfer() so an error message is printed in the syslog. Signed-off-by: Gwendal Grignou Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_sysfs.c | 25 - 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index da0a719d32f7..c03621e523a3 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c @@ -114,15 +114,9 @@ static ssize_t store_ec_reboot(struct device *dev, msg->command = EC_CMD_REBOOT_EC + ec->cmd_offset; msg->outsize = sizeof(*param); msg->insize = 0; - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); - if (ret < 0) { + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); + if (ret < 0) count = ret; - goto exit; - } - if (msg->result != EC_RES_SUCCESS) { - dev_dbg(ec->dev, "EC result %d\n", msg->result); - count = -EINVAL; - } exit: kfree(msg); return count; @@ -150,17 +144,11 @@ static ssize_t show_ec_version(struct device *dev, msg->command = EC_CMD_GET_VERSION + ec->cmd_offset; msg->insize = sizeof(*r_ver); msg->outsize = 0; - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); if (ret < 0) { count = ret; goto exit; } - if (msg->result != EC_RES_SUCCESS) { - count = scnprintf(buf, PAGE_SIZE, - "ERROR: EC returned %d\n", msg->result); - goto exit; - } - r_ver = (struct ec_response_get_version *)msg->data; /* Strings should be null-terminated, but let's be sure. */ r_ver->version_string_ro[sizeof(r_ver->version_string_ro) - 1] = '\0'; @@ -255,14 +243,9 @@ static ssize_t show_ec_flashinfo(struct device *dev, msg->command = EC_CMD_FLASH_INFO + ec->cmd_offset; msg->insize = sizeof(*resp); msg->outsize = 0; - ret = cros_ec_cmd_xfer(ec->ec_dev, msg); + ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg); if (ret < 0) goto exit; - if (msg->result != EC_RES_SUCCESS) { - ret = scnprintf(buf, PAGE_SIZE, - "ERROR: EC returned %d\n", msg->result); - goto exit; - } resp = (struct ec_response_flash_info *)msg->data; -- 2.16.1
Re: [RESEND PATCH v2 2/2] ASoC: topology: Add missing clock gating parameter when parsing hw_configs
On Tue, Feb 20, 2018 at 7:44 PM, Kirill Marinushkin wrote: > Clock gating parameter is a part of `dai_fmt`. It is supported by > `alsa-lib` when creating a topology binary file, but ignored by kernel > when loading this topology file. > + /* clock gating */ > + if (hw_config->clock_gated == SND_SOC_TPLG_DAI_CLK_GATE_GATED) > + link->dai_fmt |= SND_SOC_DAIFMT_GATED; > + else if (hw_config->clock_gated == > +SND_SOC_TPLG_DAI_CLK_GATE_CONT) A nit, I would leave it on the same line, even if it ~2-3 characters longer than 80. > + link->dai_fmt |= SND_SOC_DAIFMT_CONT; > + -- With Best Regards, Andy Shevchenko
[PATCH 2/3] platform/chrome: cros_ec_debugfs: Add PD port info to debugfs
From: Shawn Nematbakhsh Add info useful for debugging USB-PD port state. Signed-off-by: Shawn Nematbakhsh Signed-off-by: Enric Balletbo i Serra --- drivers/platform/chrome/cros_ec_debugfs.c | 86 +-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index 0328856ec3a2..1d7e28c633f2 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c @@ -35,7 +35,8 @@ #define CIRC_ADD(idx, size, value) (((idx) + (value)) & ((size) - 1)) -/* struct cros_ec_debugfs - ChromeOS EC debugging information +/* + * struct cros_ec_debugfs - ChromeOS EC debugging information * * @ec: EC device this debugfs information belongs to * @dir: dentry for debugfs files @@ -170,7 +171,8 @@ static ssize_t cros_ec_console_log_read(struct file *file, char __user *buf, mutex_lock(&debug_info->log_mutex); } - /* Only copy until the end of the circular buffer, and let userspace + /* +* Only copy until the end of the circular buffer, and let userspace * retry to get the rest of the data. */ ret = min_t(size_t, CIRC_CNT_TO_END(cb->head, cb->tail, LOG_SIZE), @@ -211,6 +213,61 @@ static int cros_ec_console_log_release(struct inode *inode, struct file *file) return 0; } +static ssize_t cros_ec_pdinfo_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + char read_buf[EC_USB_PD_MAX_PORTS * 40], *p = read_buf; + struct cros_ec_debugfs *debug_info = file->private_data; + struct cros_ec_device *ec_dev = debug_info->ec->ec_dev; + + struct { + struct cros_ec_command msg; + union { + struct ec_response_usb_pd_control_v1 resp; + struct ec_params_usb_pd_control params; + }; + } __packed ec_buf; + + struct cros_ec_command *msg; + struct ec_response_usb_pd_control_v1 *resp; + struct ec_params_usb_pd_control *params; + + int i; + + msg = &ec_buf.msg; + params = (struct ec_params_usb_pd_control *)msg->data; + resp = (struct ec_response_usb_pd_control_v1 *)msg->data; + + msg->command = EC_CMD_USB_PD_CONTROL; + msg->version = 1; + msg->insize = sizeof(*resp); + msg->outsize = sizeof(*params); + + /* +* Read status from all PD ports until failure, typically caused +* by attempting to read status on a port that doesn't exist. +*/ + for (i = 0; i < EC_USB_PD_MAX_PORTS; ++i) { + params->port = i; + params->role = 0; + params->mux = 0; + params->swap = 0; + + if (cros_ec_cmd_xfer_status(ec_dev, msg) < 0) + break; + + p += scnprintf(p, sizeof(read_buf) + read_buf - p, + "p%d: %s en:%.2x role:%.2x pol:%.2x\n", + i, resp->state, resp->enabled, resp->role, + resp->polarity); + } + + return simple_read_from_buffer(user_buf, count, ppos, + read_buf, p - read_buf); +} + const struct file_operations cros_ec_console_log_fops = { .owner = THIS_MODULE, .open = cros_ec_console_log_open, @@ -220,6 +277,13 @@ const struct file_operations cros_ec_console_log_fops = { .release = cros_ec_console_log_release, }; +const struct file_operations cros_ec_pdinfo_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = cros_ec_pdinfo_read, + .llseek = default_llseek, +}; + static int ec_read_version_supported(struct cros_ec_dev *ec) { struct ec_params_get_cmd_versions_v1 *params; @@ -288,7 +352,7 @@ static int cros_ec_create_console_log(struct cros_ec_debugfs *debug_info) init_waitqueue_head(&debug_info->log_wq); if (!debugfs_create_file("console_log", -S_IFREG | S_IRUGO, +S_IFREG | 0444, debug_info->dir, debug_info, &cros_ec_console_log_fops)) @@ -341,7 +405,7 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info) debug_info->panicinfo_blob.size = ret; if (!debugfs_create_blob("panicinfo", -S_IFREG | S_IRUGO, +S_IFREG | 0444, debug_info->dir, &debug_info->panicinfo_blob)) { ret = -ENOMEM; @@ -355,6 +419,16 @@ static int cros_ec_create_panicinfo(struct cros_ec_debugfs *debug_info) return ret; } +static int cros_ec_crea
Re: [PATCH 1/4] drm/atomic: integrate modeset lock with private objects
On Wed, Feb 21, 2018 at 09:37:21AM -0500, Rob Clark wrote: > Follow the same pattern of locking as with other state objects. This > avoids boilerplate in the driver. I'm not sure we really want to do this. What if the driver wants a custom locking scheme for this state? > > Signed-off-by: Rob Clark > --- > drivers/gpu/drm/drm_atomic.c | 9 - > include/drm/drm_atomic.h | 5 + > 2 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c > index fc8c4da409ff..004e621ab307 100644 > --- a/drivers/gpu/drm/drm_atomic.c > +++ b/drivers/gpu/drm/drm_atomic.c > @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj *obj, > { > memset(obj, 0, sizeof(*obj)); > > + drm_modeset_lock_init(&obj->lock); > + > obj->state = state; > obj->funcs = funcs; > } > @@ -1093,6 +1095,7 @@ void > drm_atomic_private_obj_fini(struct drm_private_obj *obj) > { > obj->funcs->atomic_destroy_state(obj, obj->state); > + drm_modeset_lock_fini(&obj->lock); > } > EXPORT_SYMBOL(drm_atomic_private_obj_fini); > > @@ -1113,7 +1116,7 @@ struct drm_private_state * > drm_atomic_get_private_obj_state(struct drm_atomic_state *state, >struct drm_private_obj *obj) > { > - int index, num_objs, i; > + int index, num_objs, i, ret; > size_t size; > struct __drm_private_objs_state *arr; > struct drm_private_state *obj_state; > @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct > drm_atomic_state *state, > if (obj == state->private_objs[i].ptr) > return state->private_objs[i].state; > > + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); > + if (ret) > + return ERR_PTR(ret); > + > num_objs = state->num_private_objs + 1; > size = sizeof(*state->private_objs) * num_objs; > arr = krealloc(state->private_objs, size, GFP_KERNEL); > diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h > index 09076a625637..9ae53b73c9d2 100644 > --- a/include/drm/drm_atomic.h > +++ b/include/drm/drm_atomic.h > @@ -218,6 +218,11 @@ struct drm_private_state_funcs { > * &drm_modeset_lock is required to duplicate and update this object's state. > */ > struct drm_private_obj { > + /** > + * @lock: Modeset lock to protect the state object. > + */ > + struct drm_modeset_lock lock; > + > /** >* @state: Current atomic state for this driver private object. >*/ > -- > 2.14.3 > > ___ > dri-devel mailing list > dri-de...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Ville Syrjälä Intel OTC
[PATCH 0/3] platform/chrome: cros_ec debugfs and sysfs updates
Hi, This patchset is another recopilation of some patches that were send before but never merged. First patch was already sent [1] but did not receive feedback so I am resending it. Needs to go throught platform/chrome tree and can be picked without dependencies. The second patch is new, like the first needs to go throught platform/chrome tree and can be picked without dependecies. Finally, the third patch was already sent [2] but now needed to be reworked due the split of the cros_ec_devs in 2 parts [3]. This patch touches platform/chrome and mfd so we will probably need an immutable branch when is ok. Best regards, Enric [1] https://patchwork.kernel.org/patch/9894655/ [2] https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1488891.html [3] https://lkml.org/lkml/2017/11/20/408 Gwendal Grignou (2): platform/chrome: cros_ec_sysfs: Modify error handling platform/chrome: mfd/cros_ec_dev: Add sysfs entry to set keyboard wake lid angle Shawn Nematbakhsh (1): platform/chrome: cros_ec_debugfs: Add PD port info to debugfs drivers/mfd/cros_ec_dev.c | 19 +++--- drivers/platform/chrome/cros_ec_debugfs.c | 86 ++-- drivers/platform/chrome/cros_ec_sysfs.c | 108 -- include/linux/mfd/cros_ec.h | 1 + 4 files changed, 180 insertions(+), 34 deletions(-) -- 2.16.1
Re: [PATCH v2 05/10] drm/sun4i: Add Allwinner A31 MIPI-DSI controller support
Hi Maxime, I love your patch! Perhaps something to improve: [auto build test WARNING on ] url: https://github.com/0day-ci/linux/commits/Maxime-Ripard/drm-sun4i-Allwinner-MIPI-DSI-support/20180221-203150 base: config: arm-allmodconfig (attached as .config) compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=arm All warnings (new ones prefixed by >>): drivers/gpu/drm/sun4i/sun4i_tcon.c: In function 'sun4i_tcon_mode_set': >> drivers/gpu/drm/sun4i/sun4i_tcon.c:606:30: warning: passing argument 1 of >> 'encoder_to_sun6i_dsi' discards 'const' qualifier from pointer target type >> [-Wdiscarded-qualifiers] dsi = encoder_to_sun6i_dsi(encoder); ^~~ In file included from drivers/gpu/drm/sun4i/sun4i_tcon.c:37:0: drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h:54:33: note: expected 'struct drm_encoder *' but argument is of type 'const struct drm_encoder *' static inline struct sun6i_dsi *encoder_to_sun6i_dsi(struct drm_encoder *encoder) ^~~~ vim +606 drivers/gpu/drm/sun4i/sun4i_tcon.c 593 594 void sun4i_tcon_mode_set(struct sun4i_tcon *tcon, 595 const struct drm_encoder *encoder, 596 const struct drm_display_mode *mode) 597 { 598 struct sun6i_dsi *dsi; 599 600 switch (encoder->encoder_type) { 601 case DRM_MODE_ENCODER_DSI: 602 /* 603 * This is not really elegant, but it's the "cleaner" 604 * way I could think of... 605 */ > 606 dsi = encoder_to_sun6i_dsi(encoder); 607 sun4i_tcon0_mode_set_cpu(tcon, dsi->device, mode); 608 break; 609 case DRM_MODE_ENCODER_LVDS: 610 sun4i_tcon0_mode_set_lvds(tcon, encoder, mode); 611 break; 612 case DRM_MODE_ENCODER_NONE: 613 sun4i_tcon0_mode_set_rgb(tcon, mode); 614 sun4i_tcon_set_mux(tcon, 0, encoder); 615 break; 616 case DRM_MODE_ENCODER_TVDAC: 617 case DRM_MODE_ENCODER_TMDS: 618 sun4i_tcon1_mode_set(tcon, mode); 619 sun4i_tcon_set_mux(tcon, 1, encoder); 620 break; 621 default: 622 DRM_DEBUG_DRIVER("Unknown encoder type, doing nothing...\n"); 623 } 624 } 625 EXPORT_SYMBOL(sun4i_tcon_mode_set); 626 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 0/2] Stackleak for arm64
On 21.02.2018 04:13, Laura Abbott wrote: > This is the arm64 version of the STACKLEAK plugin originall from > grsecurity. See > https://marc.info/?l=kernel-hardening&m=151880470609808 for the > full x86 version. This is based on top of Kees' branch for stackleak > and has been cleaned up to use a few macros from that branch. > > Comments welcome, if there are no major objections Kees will queue this > up to get some CI testing. This passed both of the LKDTM tests. Hello, Laura, Thank you. I'll take some time to learn your patches and test them on my LeMaker HiKey board. I'll return with the feedback. Best regards, Alexander
Re: [PATCH v2 1/2] KVM: x86: Add a framework for supporting MSR-based features
On 2/21/2018 8:32 AM, Paolo Bonzini wrote: > On 21/02/2018 15:15, Tom Lendacky wrote: >> On 2/21/2018 5:41 AM, Paolo Bonzini wrote: >>> On 16/02/2018 00:12, Tom Lendacky wrote: +static u32 msr_based_features[] = { +}; + +static unsigned int num_msr_based_features = ARRAY_SIZE(msr_based_features); + bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) { if (efer & efer_reserved_bits) @@ -2785,6 +2794,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SET_BOOT_CPU_ID: case KVM_CAP_SPLIT_IRQCHIP: case KVM_CAP_IMMEDIATE_EXIT: + case KVM_CAP_GET_MSR_FEATURES: r = 1; break; case KVM_CAP_ADJUST_CLOCK: @@ -4410,6 +4420,47 @@ long kvm_arch_vm_ioctl(struct file *filp, r = kvm_x86_ops->mem_enc_unreg_region(kvm, ®ion); break; } + case KVM_GET_MSR_INDEX_LIST: { + struct kvm_msr_list __user *user_msr_list = argp; + struct kvm_msr_list msr_list; + unsigned int n; + + r = -EFAULT; + if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list))) + goto out; + n = msr_list.nmsrs; + msr_list.nmsrs = num_msr_based_features; + if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list))) + goto out; + r = -E2BIG; + if (n < msr_list.nmsrs) + goto out; + r = -EFAULT; + if (copy_to_user(user_msr_list->indices, &msr_based_features, + num_msr_based_features * sizeof(u32))) + goto out; + r = 0; + break; >>> >>> I think it's better to have some logic in kvm_init_msr_list, to filter >>> the MSR list based on whatever MSRs the backend provides. >> >> Ok, that's what I had originally and then you said to just return the full >> list and let KVM_GET_MSR return a 0 or 1 if it was supported. I can switch >> it back. > > Hmm, I cannot find this remark (I would have been very confused, so I > tried to look for it). I commented on removing kvm_valid_msr_feature, > but not kvm_init_msr_list. I think this is the reply that sent me off on that track: https://marc.info/?l=linux-kernel&m=151862648123153&w=2 I'll make it consistent with the other MSR-related items and initialize the list in kvm_init_msr_list(). I'll change the signature of the msr_feature() kvm_x86_ops callback to take an index and optionally return a data value so it can be used to check for support when building the list and return a value when needed. Thanks, Tom > >>> + } + case KVM_GET_MSR: { >>> >>> It's not that the API isn't usable, KVM_GET_MSR is fine for what we need >>> here (it's not a fast path), but it's a bit confusing to have >>> KVM_GET_MSR and KVM_GET_MSRS. >>> >>> I see two possibilities: >>> >>> 1) reuse KVM_GET_MSRS as in the previous version. It's okay to >>> cut-and-paste code from msr_io. >> >> If I go back to trimming the list based on support, then KVM_GET_MSRS can >> be used. > > No problem, renaming is enough---I should have made a better suggestion > in the previous review. > > Paolo >
Re: [PATCH 05/10] hwmon: generic-pwm-tachometer: Add generic PWM based tachometer
On 02/20/2018 11:15 PM, Mikko Perttunen wrote: AIUI, the PWM framework already exposes a sysfs node with period information. We should just use that instead of adding a new driver for this. I am kind of lost. Please explain. Are you saying that we should drop the pwm-fan driver as well (which goes the opposite way), as well as any other drivers doing anything with pwm signals, because after all those signals are already exposed to userspace a sysfs attributes, and a kernel driver to abstract those values is thus not needed ? In any case, we cannot add something like this to device tree since it's not a hardware device. So you are saying there is no means to express in devicetree that a pwm input is connected to a fan ? How is that not hardware ? If so, how do you express in devicetree that a pwm signal is connected to anything ? Guenter Mikko On 21.02.2018 08:58, Rajkumar Rampelli wrote: Add generic PWM based tachometer driver via HWMON interface to report the RPM of motor. This drivers get the period/duty cycle from PWM IP which captures the motor PWM output. This driver implements a simple interface for monitoring the speed of a fan and exposes it in roatations per minute (RPM) to the user space by using the hwmon's sysfs interface Signed-off-by: Rajkumar Rampelli --- Documentation/hwmon/generic-pwm-tachometer | 17 + drivers/hwmon/Kconfig | 10 +++ drivers/hwmon/Makefile | 1 + drivers/hwmon/generic-pwm-tachometer.c | 112 + 4 files changed, 140 insertions(+) create mode 100644 Documentation/hwmon/generic-pwm-tachometer create mode 100644 drivers/hwmon/generic-pwm-tachometer.c diff --git a/Documentation/hwmon/generic-pwm-tachometer b/Documentation/hwmon/generic-pwm-tachometer new file mode 100644 index 000..e0713ee --- /dev/null +++ b/Documentation/hwmon/generic-pwm-tachometer @@ -0,0 +1,17 @@ +Kernel driver generic-pwm-tachometer + + +This driver enables the use of a PWM module to monitor a fan. It uses the +generic PWM interface and can be used on SoCs as along as the SoC supports +Tachometer controller that moniors the Fan speed in periods. + +Author: Rajkumar Rampelli + +Description +--- + +The driver implements a simple interface for monitoring the Fan speed using +PWM module and Tachometer controller. It requests period value through PWM +capture interface to Tachometer and measures the Rotations per minute using +received period value. It exposes the Fan speed in RPM to the user space by +using the hwmon's sysfs interface. diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index ef23553..8912dcb 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1878,6 +1878,16 @@ config SENSORS_XGENE If you say yes here you get support for the temperature and power sensors for APM X-Gene SoC. +config GENERIC_PWM_TACHOMETER + tristate "Generic PWM based tachometer driver" + depends on PWM + help + Enables a driver to use PWM signal from motor to use + for measuring the motor speed. The RPM is captured by + PWM modules which has PWM capture capability and this + drivers reads the captured data from PWM IP to convert + it to speed in RPM. + if ACPI comment "ACPI drivers" diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index f814b4a..9dcc374 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -175,6 +175,7 @@ obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o obj-$(CONFIG_SENSORS_XGENE) += xgene-hwmon.o obj-$(CONFIG_PMBUS) += pmbus/ +obj-$(CONFIG_GENERIC_PWM_TACHOMETER) += generic-pwm-tachometer.o ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG diff --git a/drivers/hwmon/generic-pwm-tachometer.c b/drivers/hwmon/generic-pwm-tachometer.c new file mode 100644 index 000..9354d43 --- /dev/null +++ b/drivers/hwmon/generic-pwm-tachometer.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include + +struct pwm_hwmon_tach { + struct device *dev; + struct pwm_device *pwm; + struct device *hwmon; +}; + +static ssize_t show_rpm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_hwmon_tach *ptt = dev_get_drvdata(dev); + struct pwm_device *pwm = ptt->pwm; + struct pwm_capture result; + int err; + unsigned int rpm
Re: [PATCH 4.4 00/33] 4.4.117-stable review
On Wed, Feb 21, 2018 at 01:44:43PM +0100, Greg Kroah-Hartman wrote: > This is the start of the stable review cycle for the 4.4.117 release. > There are 33 patches in this series, all will be posted as a response > to this one. If anyone has any issues with these being applied, please > let me know. > > Responses should be made by Fri Feb 23 12:43:54 UTC 2018. > Anything received after that time might be too late. > > The whole patch series can be found in one patch at: > > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.117-rc1.gz > or in the git tree and branch at: > > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git > linux-4.4.y > and the diffstat can be found below. > > thanks, > > greg k-h > Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5. No conflicts and no apparent issues in dmesg or general usage (I've been running the RC before this one since yesterday afternoon and not much changed for Android since then). Thanks! Nathan
Re: [PATCH] RDMA/core: reduce IB_POLL_BATCH constant
On 2/21/2018 3:44 PM, Sagi Grimberg wrote: On Tue, 2018-02-20 at 21:59 +0100, Arnd Bergmann wrote: /* # of WCs to poll for with a single call to ib_poll_cq */ -#define IB_POLL_BATCH 16 +#define IB_POLL_BATCH 8 The purpose of batch polling is to minimize contention on the cq spinlock. Reducing the IB_POLL_BATCH constant may affect performance negatively. Has the performance impact of this change been verified for all affected drivers (ib_srp, ib_srpt, ib_iser, ib_isert, NVMeOF, NVMeOF target, SMB Direct, NFS over RDMA, ...)? Only the users of the DIRECT polling method use an on-stack array of ib_wc's. This is only the SRP drivers. The other two modes have use of a dynamically allocated array of ib_wc's that hangs off the ib_cq. These shouldn't need any reduction in the size of this array, and they are the common case. IMO a better solution would be to change ib_process_cq_direct to use a smaller on-stack array, and leave IB_POLL_BATCH alone. The only reason why I added this array on-stack was to allow consumers that did not use ib_alloc_cq api to call it, but that seems like a wrong decision when thinking it over again (as probably these users did not set the wr_cqe correctly). How about we make ib_process_cq_direct use the cq wc array and add a WARN_ON statement (and fail it gracefully) if the caller used this API without calling ib_alloc_cq? but we tried to avoid cuncurrent access to cq->wc. Why can't we use the solution I wrote above ? -- diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c index bc79ca8215d7..cd3e9e124834 100644 --- a/drivers/infiniband/core/cq.c +++ b/drivers/infiniband/core/cq.c @@ -25,10 +25,10 @@ #define IB_POLL_FLAGS \ (IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) -static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) +static int __ib_process_cq(struct ib_cq *cq, int budget) { int i, n, completed = 0; - struct ib_wc *wcs = poll_wc ? : cq->wc; + struct ib_wc *wcs = cq->wc; /* * budget might be (-1) if the caller does not @@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) */ int ib_process_cq_direct(struct ib_cq *cq, int budget) { - struct ib_wc wcs[IB_POLL_BATCH]; - - return __ib_process_cq(cq, budget, wcs); + if (unlikely(WARN_ON_ONCE(!cq->wc))) + return 0; + return __ib_process_cq(cq, budget); } EXPORT_SYMBOL(ib_process_cq_direct); @@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget) struct ib_cq *cq = container_of(iop, struct ib_cq, iop); int completed; - completed = __ib_process_cq(cq, budget, NULL); + completed = __ib_process_cq(cq, budget); if (completed < budget) { irq_poll_complete(&cq->iop); if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) @@ -108,7 +108,7 @@ static void ib_cq_poll_work(struct work_struct *work) struct ib_cq *cq = container_of(work, struct ib_cq, work); int completed; - completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL); + completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE); if (completed >= IB_POLL_BUDGET_WORKQUEUE || ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) queue_work(ib_comp_wq, &cq->work); -- -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] powerpc/mm/32: Use pfn_valid to check if pointer is in RAM
On Wed, Feb 21, 2018 at 02:51:19PM +0100, Jonathan Neuschäfer wrote: [...] > While looking through arch/powerpc/mm, I noticed that there's a > page_is_ram function, which simply uses the memblocks directly, on > PPC32. Oops, I misread the code here. memblock is used on PPC64. > It seems like a good candidate for the RAM check in > __ioremap_caller, except that there's this code, which apparently > trashes memblock 0 completely on non-CONFIG_NEED_MULTIPLE_NODES: > > https://elixir.bootlin.com/linux/v4.16-rc2/source/arch/powerpc/mm/mem.c#L223 > > > Thanks, > Jonathan Neuschäfer signature.asc Description: PGP signature
Re: [tip:x86/pti] objtool, retpolines: Integrate objtool with retpoline support more closely
On Wed, Feb 21, 2018 at 10:59:14AM +, David Woodhouse wrote: > On Wed, 2018-02-21 at 02:34 -0800, tip-bot for Peter Zijlstra wrote: > > > > --- a/Makefile > > +++ b/Makefile > > @@ -489,6 +489,11 @@ KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) > > KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) > > endif > > > > +ifneq ($(call cc-option,-mindirect-branch=thunk-extern > > -mindirect-branch-register),) > > + CC_HAS_RETPOLINE := 1 > > +endif > > +export CC_HAS_RETPOLINE > > + > > That isn't the same as the check in arch/x86/Makefile. That's because this crossed with the llvm cruft, right? I'll have a look.
Re: mainline build: 15 warnings 0 failures (mainline/v4.16-rc2-64-gaf3e79d)
On Wednesday 21 February 2018 06:12 PM, Arnd Bergmann wrote: > On Tue, Feb 20, 2018 at 7:34 PM, Olof's autobuilder wrote: >> Here are the build results from automated periodic testing. >> >> The tree being built was mainline, found at: >> >> URL: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git >> >> >> Warnings: >> >> arm64.allmodconfig: >> include/uapi/linux/byteorder/big_endian.h:31:52: warning: passing argument 1 >> of '__fswab64' makes integer from pointer without a cast [-Wint-conversion] > > I sent two patches to the bnxt_re maintainers yesterday. I expect them > to get applied > soon, but haven't heard back yet. > >> WARNING: modpost: missing MODULE_LICENSE() in >> drivers/phy/qualcomm/phy-qcom-ufs.o > > Still waiting for Kishon to apply an older patch I sent for this. I had merged it locally. Now pushed everything. Thanks Kishon > >> arm.allmodconfig: >> /tmp/ccQBDjc9.s:18123: Warning: using r15 results in unpredictable behaviour >> /tmp/ccQBDjc9.s:18195: Warning: using r15 results in unpredictable behaviour > > I have done multiple versions of a patch for this, none was > universally liked, but > we need to decide on one of them. > >> include/linux/bitops.h:7:24: warning: left shift count >= width of type >> [-Wshift-count-overflow] >> include/linux/bitops.h:7:24: warning: left shift count >= width of type >> [-Wshift-count-overflow] >> include/linux/bitops.h:7:24: warning: left shift count >= width of type >> [-Wshift-count-overflow] >> drivers/infiniband/hw/bnxt_re/qplib_fp.c:333:23: warning: cast to pointer >> from integer of different size [-Wint-to-pointer-cast] >> drivers/infiniband/hw/bnxt_re/qplib_fp.c:336:12: warning: cast to pointer >> from integer of different size [-Wint-to-pointer-cast] >> include/uapi/linux/swab.h:127:46: warning: cast from pointer to integer of >> different size [-Wpointer-to-int-cast] > > Also bnxt_re, same as above > >> drivers/infiniband/core/cq.c:78:1: warning: the frame size of 1032 bytes is >> larger than 1024 bytes [-Wframe-larger-than=] > > Sent a patch yesterday, my workaround was suboptimal, discussion about > a better fix > is ongoing. > >> arm.spear3xx_defconfig: >> net/core/filter.c:3382:6: warning: unused variable 'val' [-Wunused-variable] >> >> arm.spear6xx_defconfig: >> net/core/filter.c:3382:6: warning: unused variable 'val' [-Wunused-variable] >> >> arm.tct_hammer_defconfig: >> net/core/filter.c:3382:6: warning: unused variable 'val' [-Wunused-variable] > > Sent two versions of a patch yesterday, the second version was applied and > should make it into mainline next week. > >Arnd >
Re: [PATCH 0/6] DISCONTIGMEM support for PPC32
Hi, On Wed, Feb 21, 2018 at 08:06:10AM +0100, Christophe LEROY wrote: > > > Le 20/02/2018 à 17:14, Jonathan Neuschäfer a écrit : > > This patchset adds support for DISCONTIGMEM on 32-bit PowerPC. This is > > required to properly support the Nintendo Wii's memory layout, in which > > there are two blocks of RAM and MMIO in the middle. > > > > Previously, this memory layout was handled by code that joins the two > > RAM blocks into one, reserves the MMIO hole, and permits allocations of > > reserved memory in ioremap. This hack didn't work with resource-based > > allocation (as used for example in the GPIO driver for Wii[1]), however. > > > > After this patchset, users of the Wii can either select CONFIG_FLATMEM > > to get the old behaviour, or CONFIG_DISCONTIGMEM to get the new > > behaviour. > > My question might me stupid, as I don't know PCC64 in deep, but when looking > at page_is_ram() in arch/powerpc/mm/mem.c, I have the feeling the PPC64 > implements ram by blocks. Isn't it what you are trying to achieve ? Wouldn't > it be feasible to map to what's done in PPC64 for PPC32 ? Using page_is_ram in __ioremap_caller and the same memblock-based approach that's used on PPC64 on PPC32 *should* work, but I think due to the following line in initmem_init, it won't: memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0); Thanks, Jonathan Neuschäfer signature.asc Description: PGP signature
[PATCH v2] crypto: ccp: add check to get PSP master only when PSP is detected
Paulian reported the below kernel crash on Ryzen 5 system: BUG: unable to handle kernel NULL pointer dereference at 0073 RIP: 0010:.LC0+0x41f/0xa00 RSP: 0018:a9968003bdd0 EFLAGS: 00010002 RAX: b113b130 RBX: RCX: 05a7 RDX: 00ff RSI: 8b46dee651a0 RDI: b1bd617c RBP: 0246 R08: 000251a0 R09: R10: d81f11a38200 R11: 8b52e8e0a161 R12: b19db220 R13: 0007 R14: b17e4888 R15: 5dccd7affc30a31e FS: () GS:8b46dee4() knlGS: CR2: 0073 CR3: 80128120a000 CR4: 003406e0 Call Trace: ? sp_get_psp_master_device+0x56/0x80 ? map_properties+0x540/0x540 ? psp_pci_init+0x20/0xe0 ? map_properties+0x540/0x540 ? sp_mod_init+0x16/0x1a ? do_one_initcall+0x4b/0x190 ? kernel_init_freeable+0x19b/0x23c ? rest_init+0xb0/0xb0 ? kernel_init+0xa/0x100 ? ret_from_fork+0x22/0x40 Since Ryzen does not support PSP/SEV firmware hence i->psp_data will NULL in all sp instances. In those cases, 'i' will point to the list head after list_for_each_entry(). Dereferencing the head will cause kernel crash. Add check to call get master device only when PSP/SEV is detected. Reported-by: Paulian Bogdan Marinca Cc: Borislav Petkov Cc: Tom Lendacky CC: Gary R Hook Cc: linux-kernel@vger.kernel.org Signed-off-by: Brijesh Singh --- Changes since v1: v1 contained a local change I used for triggering the crash on EPYC system. we do not need those changes in final patch. drivers/crypto/ccp/sp-dev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index eb0da6572720..e0459002eb71 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -252,12 +252,12 @@ struct sp_device *sp_get_psp_master_device(void) goto unlock; list_for_each_entry(i, &sp_units, entry) { - if (i->psp_data) + if (i->psp_data && i->get_psp_master_device) { + ret = i->get_psp_master_device(); break; + } } - if (i->get_psp_master_device) - ret = i->get_psp_master_device(); unlock: write_unlock_irqrestore(&sp_unit_lock, flags); return ret; -- 2.14.3
[PATCH 4.9 06/77] jbd2: fix sphinx kernel-doc build warnings
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Tobin C. Harding commit f69120ce6c024aa634a8fc25787205e42f0ccbe6 upstream. Sphinx emits various (26) warnings when building make target 'htmldocs'. Currently struct definitions contain duplicate documentation, some as kernel-docs and some as standard c89 comments. We can reduce duplication while cleaning up the kernel docs. Move all kernel-docs to right above each struct member. Use the set of all existing comments (kernel-doc and c89). Add documentation for missing struct members and function arguments. Signed-off-by: Tobin C. Harding Signed-off-by: Theodore Ts'o Cc: sta...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/jbd2/transaction.c |5 include/linux/jbd2.h | 431 +++--- 2 files changed, 272 insertions(+), 164 deletions(-) --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -488,8 +488,10 @@ void jbd2_journal_free_reserved(handle_t EXPORT_SYMBOL(jbd2_journal_free_reserved); /** - * int jbd2_journal_start_reserved(handle_t *handle) - start reserved handle + * int jbd2_journal_start_reserved() - start reserved handle * @handle: handle to start + * @type: for handle statistics + * @line_no: for handle statistics * * Start handle that has been previously reserved with jbd2_journal_reserve(). * This attaches @handle to the running transaction (or creates one if there's @@ -619,6 +621,7 @@ error_out: * int jbd2_journal_restart() - restart a handle . * @handle: handle to restart * @nblocks: nr credits requested + * @gfp_mask: memory allocation flags (for start_this_handle) * * Restart a handle for a multi-transaction filesystem * operation. --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -418,26 +418,41 @@ static inline void jbd_unlock_bh_journal #define JI_WAIT_DATA (1 << __JI_WAIT_DATA) /** - * struct jbd_inode is the structure linking inodes in ordered mode - * present in a transaction so that we can sync them during commit. + * struct jbd_inode - The jbd_inode type is the structure linking inodes in + * ordered mode present in a transaction so that we can sync them during commit. */ struct jbd2_inode { - /* Which transaction does this inode belong to? Either the running -* transaction or the committing one. [j_list_lock] */ + /** +* @i_transaction: +* +* Which transaction does this inode belong to? Either the running +* transaction or the committing one. [j_list_lock] +*/ transaction_t *i_transaction; - /* Pointer to the running transaction modifying inode's data in case -* there is already a committing transaction touching it. [j_list_lock] */ + /** +* @i_next_transaction: +* +* Pointer to the running transaction modifying inode's data in case +* there is already a committing transaction touching it. [j_list_lock] +*/ transaction_t *i_next_transaction; - /* List of inodes in the i_transaction [j_list_lock] */ + /** +* @i_list: List of inodes in the i_transaction [j_list_lock] +*/ struct list_head i_list; - /* VFS inode this inode belongs to [constant during the lifetime -* of the structure] */ + /** +* @i_vfs_inode: +* +* VFS inode this inode belongs to [constant for lifetime of structure] +*/ struct inode *i_vfs_inode; - /* Flags of inode [j_list_lock] */ + /** +* @i_flags: Flags of inode [j_list_lock] +*/ unsigned long i_flags; }; @@ -447,12 +462,20 @@ struct jbd2_revoke_table_s; * struct handle_s - The handle_s type is the concrete type associated with * handle_t. * @h_transaction: Which compound transaction is this update a part of? + * @h_journal: Which journal handle belongs to - used iff h_reserved set. + * @h_rsv_handle: Handle reserved for finishing the logical operation. * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. - * @h_ref: Reference count on this handle - * @h_err: Field for caller's use to track errors through large fs operations - * @h_sync: flag for sync-on-close - * @h_jdata: flag to force data journaling - * @h_aborted: flag indicating fatal error on handle + * @h_ref: Reference count on this handle. + * @h_err: Field for caller's use to track errors through large fs operations. + * @h_sync: Flag for sync-on-close. + * @h_jdata: Flag to force data journaling. + * @h_reserved: Flag for handle for reserved credits. + * @h_aborted: Flag indicating fatal error on handle. + * @h_type: For handle statistics. + * @h_line_no: For handle statistics. + * @h_start_jiffies: Handle Start time. + * @h_requested_credits: Holds @h_buffer_credits after handle is started. + * @saved_alloc_context: Saved context while transaction is open. **/ /* Docbook can
[PATCH 4.9 18/77] Btrfs: fix deadlock in run_delalloc_nocow
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Liu Bo commit e89166990f11c3f21e1649d760dd35f9e410321c upstream. @cur_offset is not set back to what it should be (@cow_start) if btrfs_next_leaf() returns something wrong, and the range [cow_start, cur_offset) remains locked forever. cc: Signed-off-by: Liu Bo Reviewed-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/inode.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1320,8 +1320,11 @@ next_slot: leaf = path->nodes[0]; if (path->slots[0] >= btrfs_header_nritems(leaf)) { ret = btrfs_next_leaf(root, path); - if (ret < 0) + if (ret < 0) { + if (cow_start != (u64)-1) + cur_offset = cow_start; goto error; + } if (ret > 0) break; leaf = path->nodes[0];
[PATCH 4.9 17/77] target/iscsi: avoid NULL dereference in CHAP auth error path
4.9-stable review patch. If anyone has any objections, please let me know. -- From: David Disseldorp commit ce512d79d0466a604793addb6b769d12ee326822 upstream. If chap_server_compute_md5() fails early, e.g. via CHAP_N mismatch, then crypto_free_shash() is called with a NULL pointer which gets dereferenced in crypto_shash_tfm(). Fixes: 69110e3cedbb ("iscsi-target: Use shash and ahash") Suggested-by: Markus Elfring Signed-off-by: David Disseldorp Cc: sta...@vger.kernel.org # 4.6+ Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/iscsi/iscsi_target_auth.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -413,7 +413,8 @@ static int chap_server_compute_md5( auth_ret = 0; out: kzfree(desc); - crypto_free_shash(tfm); + if (tfm) + crypto_free_shash(tfm); kfree(challenge); kfree(challenge_binhex); return auth_ret;
[PATCH 4.9 16/77] rtlwifi: rtl8821ae: Fix connection lost problem correctly
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Larry Finger commit c713fb071edc0efc01a955f65a006b0e1795d2eb upstream. There has been a coding error in rtl8821ae since it was first introduced, namely that an 8-bit register was read using a 16-bit read in _rtl8821ae_dbi_read(). This error was fixed with commit 40b368af4b75 ("rtlwifi: Fix alignment issues"); however, this change led to instability in the connection. To restore stability, this change was reverted in commit b8b8b16352cd ("rtlwifi: rtl8821ae: Fix connection lost problem"). Unfortunately, the unaligned access causes machine checks in ARM architecture, and we were finally forced to find the actual cause of the problem on x86 platforms. Following a suggestion from Pkshih , it was found that increasing the ASPM L1 latency from 0 to 7 fixed the instability. This parameter was varied to see if a smaller value would work; however, it appears that 7 is the safest value. A new symbol is defined for this quantity, thus it can be easily changed if necessary. Fixes: b8b8b16352cd ("rtlwifi: rtl8821ae: Fix connection lost problem") Cc: Stable # 4.14+ Fix-suggested-by: Pkshih Signed-off-by: Larry Finger Tested-by: James Cameron # x86_64 OLPC NL3 Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c |5 +++-- drivers/net/wireless/realtek/rtlwifi/wifi.h |1 + 2 files changed, 4 insertions(+), 2 deletions(-) --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -1128,7 +1128,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl } if (0 == tmp) { read_addr = REG_DBI_RDATA + addr % 4; - ret = rtl_read_word(rtlpriv, read_addr); + ret = rtl_read_byte(rtlpriv, read_addr); } return ret; } @@ -1170,7 +1170,8 @@ static void _rtl8821ae_enable_aspm_back_ } tmp = _rtl8821ae_dbi_read(rtlpriv, 0x70f); - _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7)); + _rtl8821ae_dbi_write(rtlpriv, 0x70f, tmp | BIT(7) | +ASPM_L1_LATENCY << 3); tmp = _rtl8821ae_dbi_read(rtlpriv, 0x719); _rtl8821ae_dbi_write(rtlpriv, 0x719, tmp | BIT(3) | BIT(4)); --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -99,6 +99,7 @@ #define RTL_USB_MAX_RX_COUNT 100 #define QBSS_LOAD_SIZE 5 #define MAX_WMMELE_LENGTH 64 +#define ASPM_L1_LATENCY7 #define TOTAL_CAM_ENTRY32
[PATCH 4.9 19/77] Btrfs: fix crash due to not cleaning up tree log blocks dirty bits
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Liu Bo commit 1846430c24d66e85cc58286b3319c82cd54debb2 upstream. In cases that the whole fs flips into readonly status due to failures in critical sections, then log tree's blocks are still dirty, and this leads to a crash during umount time, the crash is about use-after-free, umount -> close_ctree -> stop workers -> iput(btree_inode) -> iput_final -> write_inode_now -> ... -> queue job on stop'd workers cc: v3.12+ Fixes: 681ae50917df ("Btrfs: cleanup reserved space when freeing tree log on error") Signed-off-by: Liu Bo Reviewed-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/tree-log.c |9 + 1 file changed, 9 insertions(+) --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2463,6 +2463,9 @@ static noinline int walk_down_log_tree(s next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } WARN_ON(root_owner != @@ -2542,6 +2545,9 @@ static noinline int walk_up_log_tree(str next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID); @@ -2618,6 +2624,9 @@ static int walk_log_tree(struct btrfs_tr clean_tree_block(trans, log->fs_info, next); btrfs_wait_tree_block_writeback(next); btrfs_tree_unlock(next); + } else { + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags)) + clear_extent_buffer_dirty(next); } WARN_ON(log->root_key.objectid !=
[PATCH 4.9 22/77] Btrfs: fix unexpected -EEXIST when creating new inode
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Liu Bo commit 900c9981680067573671ecc5cbfa7c5770be3a40 upstream. The highest objectid, which is assigned to new inode, is decided at the time of initializing fs roots. However, in cases where log replay gets processed, the btree which fs root owns might be changed, so we have to search it again for the highest objectid, otherwise creating new inode would end up with -EEXIST. cc: v4.4-rc6+ Fixes: f32e48e92596 ("Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots") Signed-off-by: Liu Bo Reviewed-by: Josef Bacik Signed-off-by: David Sterba Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/tree-log.c | 18 ++ 1 file changed, 18 insertions(+) --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -28,6 +28,7 @@ #include "hash.h" #include "compression.h" #include "qgroup.h" +#include "inode-map.h" /* magic values for the inode_only field in btrfs_log_inode: * @@ -5661,6 +5662,23 @@ again: path); } + if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) { + struct btrfs_root *root = wc.replay_dest; + + btrfs_release_path(path); + + /* +* We have just replayed everything, and the highest +* objectid of fs roots probably has changed in case +* some inode_item's got replayed. +* +* root->objectid_mutex is not acquired as log replay +* could only happen during mount. +*/ + ret = btrfs_find_highest_objectid(root, + &root->highest_objectid); + } + key.offset = found_key.offset - 1; wc.replay_dest->log_root = NULL; free_extent_buffer(log->node);
Re: [PATCH] arm64: cpufeature: Trim feature reporting and include PAN emulation
On Wed, Feb 21, 2018 at 11:18:27AM +, Dave Martin wrote: > On Tue, Feb 20, 2018 at 02:46:24PM -0800, Kees Cook wrote: > > The PAN emulation notification was only happening for non-boot CPUs > > if CPU capabilities had already been configured. This seems to be the > > wrong place, as it's system-wide and isn't attached to capabilities, > > so its reporting didn't normally happen. Instead, report it once from > > the boot CPU. Additionally removes the redundant "feature" word from the > > "CPU features:" line. > > > > Before (redundant "feature", and missing PAN emulation report): > > > > SMP: Total of 4 processors activated. > > CPU features: detected feature: 32-bit EL0 Support > > CPU features: detected feature: Kernel page table isolation (KPTI) > > CPU: All CPU(s) started at EL2 > > > > After: > > > > SMP: Total of 4 processors activated. > > CPU features: detected: 32-bit EL0 Support > > CPU features: detected: Kernel page table isolation (KPTI) > > CPU features: emulated: Privileged Access Never (PAN) using TTBR0_EL1 > > switching > > CPU: All CPU(s) started at EL2 > > > > Signed-off-by: Kees Cook > > --- > > arch/arm64/kernel/cpufeature.c | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > > index 29b1f873e337..6c799ca58b53 100644 > > --- a/arch/arm64/kernel/cpufeature.c > > +++ b/arch/arm64/kernel/cpufeature.c > > @@ -1333,9 +1333,6 @@ static void verify_local_cpu_capabilities(void) > > > > if (system_supports_sve()) > > verify_sve_features(); > > - > > - if (system_uses_ttbr0_pan()) > > - pr_info("Emulating Privileged Access Never (PAN) using > > TTBR0_EL1 switching\n"); > > } > > > > void check_local_cpu_capabilities(void) > > @@ -1360,7 +1357,7 @@ void check_local_cpu_capabilities(void) > > > > static void __init setup_feature_capabilities(void) > > { > > - update_cpu_capabilities(arm64_features, "detected feature:"); > > + update_cpu_capabilities(arm64_features, "detected:"); > > Although I get what you're saying about redundant use of the word > "features", this feels like cosmetic churn that is unrelated to the > problem this patch is addressing. Given it seems sensible, shall we just split that into a separate patch? FWIW, for a patch with just this change: Acked-by: Mark Rutland > It could be worth reviewing the CPU errata messages and other > miscellaneous printks together to make them less verbose and more > consistent all in one go, but that would be a separate patch... > > > enable_cpu_capabilities(arm64_features); > > } > > > > @@ -1394,6 +1391,9 @@ void __init setup_cpu_features(void) > > if (system_supports_32bit_el0()) > > setup_elf_hwcaps(compat_elf_hwcaps); > > > > + if (system_uses_ttbr0_pan()) > > + pr_info("emulated: Privileged Access Never (PAN) using > > TTBR0_EL1 switching\n"); > > + > > Moving this seems sensible. The other option would be to paste it into > update_cpu_capabilities(), but the message would still potentially get > printed multiple times, so that doesn't feel like the right approach. I think that more ideally, we'd give this an entry in the arm64_features array, but because it's effectively a negative feature, it's a little tricky. This also looks fine to me, so FWIW: Acked-by: Mark Rutland Mark.
Re: [PATCH 2/2] perf, tools, stat: Reset ids counter when retrying events
On Wed, Feb 21, 2018 at 11:00:02AM -0300, Arnaldo Carvalho de Melo wrote: > Em Thu, Oct 05, 2017 at 07:00:29PM -0700, Andi Kleen escreveu: > > From: Andi Kleen > > > > perf stat can retry opening events. After opening an file descriptor > > it adds the ids to the ecsel. Each event keeps a running > > count of ids. > > Ok, and that is done in perf_evlist__id_add() where we also add things > to the evlist->heads hashtable, shouldn't we remove all these before > retrying? I.e. perf_evlist__close() shouldn't be resetting that > hashtable? > > I.e. like in the following patch? Jiri? Namhyung? > > diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c > index 7b7d535396f7..e8942456106e 100644 > --- a/tools/perf/util/evlist.c > +++ b/tools/perf/util/evlist.c > @@ -37,13 +37,18 @@ > #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) > #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) > > -void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, > -struct thread_map *threads) > +static void perf_evlist__init_heads(struct perf_evlist *evlist) > { > int i; > > for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) > INIT_HLIST_HEAD(&evlist->heads[i]); > +} > + > +void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, > +struct thread_map *threads) > +{ > + perf_evlist__init_heads(evlist); > INIT_LIST_HEAD(&evlist->entries); > perf_evlist__set_maps(evlist, cpus, threads); > fdarray__init(&evlist->pollfd, 64); > @@ -1381,8 +1386,11 @@ void perf_evlist__close(struct perf_evlist *evlist) > { > struct perf_evsel *evsel; > > - evlist__for_each_entry_reverse(evlist, evsel) > + evlist__for_each_entry_reverse(evlist, evsel) { > perf_evsel__close(evsel); > + } > + > + perf_evlist__init_heads(evlist); > } > > static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c > index ef351688b797..fba708bc9d98 100644 > --- a/tools/perf/util/evsel.c > +++ b/tools/perf/util/evsel.c > @@ -1932,6 +1932,7 @@ void perf_evsel__close(struct perf_evsel *evsel) > > perf_evsel__close_fd(evsel); > perf_evsel__free_fd(evsel); > + evsel->ids = 0; > } yes, that seems correct jirka
Re: [PATCH v3] Handle vendor defined behavior in tcpci_init, tcpci_set_vconn and export tcpci_irq. More operations can be extended in tcpci_data if needed. According to TCPCI specification, 4.4.5.2 RO
On Wed, Feb 21, 2018 at 10:30:34PM +0800, ShuFanLee wrote: > From: ShuFanLee > > Signed-off-by: ShuFanLee Something went really wrong with your subject line :( Please fix and try again. thanks, greg k-h
[PATCH 3/4] drm/msm/mdp5: Use the new private_obj state
From: Archit Taneja This replaces the usage of the subclassed atomic state (mdp5_state) with a private_obj state embedded within drm_atomic_state. The latter method is the preferred approach, since it's simpler to implement and less prone to errors. The new API replaces the older and equivalent mdp5_state usage in the following pattern: - References to "mdp5_kms->state" (i.e, the old/existing state) is replaced with mdp5_get_existing_global_state(). In the atomic_check path, this should be called with the glob_state_lock drm_modeset_lock alredy taken. - References to "mdp5_get_state()" are replaced with mdp5_get_global_state(). This acquires glob_state_lock and uses drm_atomic_get_private_obj_state() to create a new duplicated state. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 10 -- drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 12 ++-- drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c | 20 +++- drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c | 17 - 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 0f314c1f3e8a..a7e80ebf0207 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -183,11 +183,14 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct device *dev = &mdp5_kms->pdev->dev; + struct mdp5_global_state *global_state; + + global_state = mdp5_get_existing_global_state(mdp5_kms); pm_runtime_get_sync(dev); if (mdp5_kms->smp) - mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp); + mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp); } static void mdp5_commit(struct msm_kms *kms, struct drm_atomic_state *state) @@ -209,9 +212,12 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); struct device *dev = &mdp5_kms->pdev->dev; + struct mdp5_global_state *global_state; + + global_state = mdp5_get_existing_global_state(mdp5_kms); if (mdp5_kms->smp) - mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp); + mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp); pm_runtime_put_sync(dev); } diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c index 8a00991f03c7..113e6b569562 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c @@ -52,14 +52,14 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); - struct mdp5_state *state = mdp5_get_state(s); + struct mdp5_global_state *global_state = mdp5_get_global_state(s); struct mdp5_hw_mixer_state *new_state; int i; - if (IS_ERR(state)) - return PTR_ERR(state); + if (IS_ERR(global_state)) + return PTR_ERR(global_state); - new_state = &state->hwmixer; + new_state = &global_state->hwmixer; for (i = 0; i < mdp5_kms->num_hwmixers; i++) { struct mdp5_hw_mixer *cur = mdp5_kms->hwmixers[i]; @@ -129,8 +129,8 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) { - struct mdp5_state *state = mdp5_get_state(s); - struct mdp5_hw_mixer_state *new_state = &state->hwmixer; + struct mdp5_global_state *global_state = mdp5_get_global_state(s); + struct mdp5_hw_mixer_state *new_state = &global_state->hwmixer; if (!mixer) return; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c index ff52c49095f9..1ef26bc63163 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -24,17 +24,19 @@ int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane, { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); - struct mdp5_state *state; + struct mdp5_global_state *new_global_state, *old_global_state; struct mdp5_hw_pipe_state *old_state, *new_state; int i, j; - state = mdp5_get_state(s); - if (IS_ERR(state)) - return PTR_ERR(state); + new_global_state = mdp5_get_global_state(s); + if (IS_ERR(new_global_state)) + return PTR_ERR(new_global_state); - /* grab old_state afte
[PATCH 4/4] drm/msm: Don't subclass drm_atomic_state anymore
From: Archit Taneja With the addition of "private_objs" in drm_atomic_state, we no longer need to subclass drm_atomic_state to store state of share resources that don't perfectly fit within planes/crtc/connector state information. We can now save this state within drm_atomic_state itself using the private objects. Remove the infrastructure that allowed subclassing of drm_atomic_state in the driver. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 46 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 22 --- drivers/gpu/drm/msm/msm_atomic.c | 31 - drivers/gpu/drm/msm/msm_drv.c| 3 --- drivers/gpu/drm/msm/msm_kms.h| 14 -- 5 files changed, 116 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index a7e80ebf0207..da9c4a4eb050 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -70,42 +70,6 @@ static int mdp5_hw_init(struct msm_kms *kms) return 0; } -struct mdp5_state *mdp5_get_state(struct drm_atomic_state *s) -{ - struct msm_drm_private *priv = s->dev->dev_private; - struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); - struct msm_kms_state *state = to_kms_state(s); - struct mdp5_state *new_state; - int ret; - - if (state->state) - return state->state; - - ret = drm_modeset_lock(&mdp5_kms->state_lock, s->acquire_ctx); - if (ret) - return ERR_PTR(ret); - - new_state = kmalloc(sizeof(*mdp5_kms->state), GFP_KERNEL); - if (!new_state) - return ERR_PTR(-ENOMEM); - - /* Copy state: */ - new_state->hwpipe = mdp5_kms->state->hwpipe; - new_state->hwmixer = mdp5_kms->state->hwmixer; - if (mdp5_kms->smp) - new_state->smp = mdp5_kms->state->smp; - - state->state = new_state; - - return new_state; -} - -static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state) -{ - struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); - swap(to_kms_state(state)->state, mdp5_kms->state); -} - /* Global/shared object state funcs */ /* @@ -323,7 +287,6 @@ static const struct mdp_kms_funcs kms_funcs = { .irq = mdp5_irq, .enable_vblank = mdp5_enable_vblank, .disable_vblank = mdp5_disable_vblank, - .swap_state = mdp5_swap_state, .prepare_commit = mdp5_prepare_commit, .commit = mdp5_commit, .complete_commit = mdp5_complete_commit, @@ -859,8 +822,6 @@ static void mdp5_destroy(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); drm_atomic_private_obj_fini(&mdp5_kms->glob_state); - - kfree(mdp5_kms->state); } static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt, @@ -1013,13 +974,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) mdp5_kms->dev = dev; mdp5_kms->pdev = pdev; - drm_modeset_lock_init(&mdp5_kms->state_lock); - mdp5_kms->state = kzalloc(sizeof(*mdp5_kms->state), GFP_KERNEL); - if (!mdp5_kms->state) { - ret = -ENOMEM; - goto fail; - } - ret = mdp5_global_obj_init(mdp5_kms); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h index 1c70aac20a98..a75fbd3aeaf7 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h @@ -30,8 +30,6 @@ #include "mdp5_ctl.h" #include "mdp5_smp.h" -struct mdp5_state; - struct mdp5_kms { struct mdp_kms base; @@ -51,12 +49,6 @@ struct mdp5_kms { struct mdp5_cfg_handler *cfg; uint32_t caps; /* MDP capabilities (MDP_CAP_XXX bits) */ - /** -* Global atomic state. Do not access directly, use mdp5_get_state() -*/ - struct mdp5_state *state; - struct drm_modeset_lock state_lock; - /* * Global private object state, Do not access directly, use * mdp5_global_get_state() @@ -89,20 +81,6 @@ struct mdp5_kms { }; #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) -/* Global atomic state for tracking resources that are shared across - * multiple kms objects (planes/crtcs/etc). - * - * For atomic updates which require modifying global state, - */ -struct mdp5_state { - struct mdp5_hw_pipe_state hwpipe; - struct mdp5_hw_mixer_state hwmixer; - struct mdp5_smp_state smp; -}; - -struct mdp5_state *__must_check -mdp5_get_state(struct drm_atomic_state *s); - /* Global private object state for tracking resources that are shared across * multiple kms objects (planes/crtcs/etc). */ diff --git a/d
Re: [PATCH v2 2/7] i3c: Add core I3C infrastructure
On Wed, Feb 21, 2018 at 03:22:48PM +0100, Boris Brezillon wrote: > Hi Greg, > > On Tue, 19 Dec 2017 10:36:43 +0100 > Greg Kroah-Hartman wrote: > > > On Tue, Dec 19, 2017 at 10:28:58AM +0100, Boris Brezillon wrote: > > > On Tue, 19 Dec 2017 10:21:19 +0100 > > > Greg Kroah-Hartman wrote: > > > > > > > On Tue, Dec 19, 2017 at 10:13:36AM +0100, Boris Brezillon wrote: > > > > > On Tue, 19 Dec 2017 10:09:00 +0100 > > > > > Boris Brezillon wrote: > > > > > > > > > > > On Tue, 19 Dec 2017 09:52:50 +0100 > > > > > > Greg Kroah-Hartman wrote: > > > > > > > > > > > > > On Thu, Dec 14, 2017 at 04:16:05PM +0100, Boris Brezillon wrote: > > > > > > > > > > > > > > > +/** > > > > > > > > + * i3c_device_match_id() - Find the I3C device ID entry > > > > > > > > matching an I3C dev > > > > > > > > + * @i3cdev: the I3C device we're searching a match for > > > > > > > > + * @id_table: the I3C device ID table > > > > > > > > + * > > > > > > > > + * Return: a pointer to the first entry matching @i3cdev, or > > > > > > > > NULL if there's > > > > > > > > + *no match. > > > > > > > > + */ > > > > > > > > +const struct i3c_device_id * > > > > > > > > +i3c_device_match_id(struct i3c_device *i3cdev, > > > > > > > > + const struct i3c_device_id *id_table) > > > > > > > > +{ > > > > > > > > + const struct i3c_device_id *id; > > > > > > > > + > > > > > > > > + /* > > > > > > > > +* The lower 32bits of the provisional ID is just > > > > > > > > filled with a random > > > > > > > > +* value, try to match using DCR info. > > > > > > > > +*/ > > > > > > > > + if (!I3C_PID_RND_LOWER_32BITS(i3cdev->info.pid)) { > > > > > > > > + u16 manuf = I3C_PID_MANUF_ID(i3cdev->info.pid); > > > > > > > > + u16 part = I3C_PID_PART_ID(i3cdev->info.pid); > > > > > > > > + u16 ext_info = > > > > > > > > I3C_PID_EXTRA_INFO(i3cdev->info.pid); > > > > > > > > + > > > > > > > > + /* First try to match by manufacturer/part ID. > > > > > > > > */ > > > > > > > > + for (id = id_table; id->match_flags != 0; id++) > > > > > > > > { > > > > > > > > + if ((id->match_flags & > > > > > > > > I3C_MATCH_MANUF_AND_PART) != > > > > > > > > + I3C_MATCH_MANUF_AND_PART) > > > > > > > > + continue; > > > > > > > > + > > > > > > > > + if (manuf != id->manuf_id || part != > > > > > > > > id->part_id) > > > > > > > > + continue; > > > > > > > > + > > > > > > > > + if ((id->match_flags & > > > > > > > > I3C_MATCH_EXTRA_INFO) && > > > > > > > > + ext_info != id->extra_info) > > > > > > > > + continue; > > > > > > > > + > > > > > > > > + return id; > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > + /* Fallback to DCR match. */ > > > > > > > > + for (id = id_table; id->match_flags != 0; id++) { > > > > > > > > + if ((id->match_flags & I3C_MATCH_DCR) && > > > > > > > > + id->dcr == i3cdev->info.dcr) > > > > > > > > + return id; > > > > > > > > + } > > > > > > > > + > > > > > > > > + return NULL; > > > > > > > > +} > > > > > > > > +EXPORT_SYMBOL_GPL(i3c_device_match_id); > > > > > > > > > > > > > > I just picked one random export here, but it feels like you are > > > > > > > exporting a bunch of symbols you don't need to. Why would > > > > > > > something > > > > > > > outside of the i3c "core" need to call this function? > > > > > > > > > > > > Because I'm not passing the i3c_device_id to the ->probe() method, > > > > > > and > > > > > > if the driver is supporting different variants of the device, it may > > > > > > want to know which one is being probed. > > > > > > > > > > > > I considered retrieving this information in the core just before > > > > > > probing > > > > > > the driver and passing it to the ->probe() function, but it means > > > > > > having an extra i3c_device_match_id() call for everyone even those > > > > > > who > > > > > > don't care about the device_id information, so I thought exporting > > > > > > this > > > > > > function was a good alternative (device drivers can use it when they > > > > > > actually need to retrieve the device_id). > > > > > > > > > > > > Anyway, that's something I can change if you think passing the > > > > > > i3c_device_id to the ->probe() method is preferable. > > > > > > > > > > > > > Have you looked > > > > > > > to see if you really have callers for everything you are > > > > > > > exporting? > > > > > > > > > > > > Yes, I tried to only export functions that I think will be needed by > > > > > > I3C device drivers and I3C master drivers. Note that I didn't post > > > > > > the > >
Re: [PATCH 1/2] perf, tools, stat: Use xyarray dimensions to iterate fds
Em Wed, Feb 21, 2018 at 03:33:11PM +0100, Jiri Olsa escreveu: > On Thu, Oct 05, 2017 at 07:00:28PM -0700, Andi Kleen wrote: > > From: Andi Kleen > > > > Now that the xyarray stores the dimensions we can use those > > to iterate over the FDs for a evsel. > > > > Signed-off-by: Andi Kleen > > Acked-by: Jiri Olsa Thanks, applied, and also sorry for having overlooked this :-\ - Arnaldo
[PATCH 2/4] drm/msm/mdp5: Add global state as a private atomic object
From: Archit Taneja Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are implemented as a part of atomic state by subclassing drm_atomic_state. The preferred approach is to use the drm_private_obj infrastructure available in the atomic core. mdp5_global_state is introduced as a drm atomic private object. The two funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are the two variants that will be used to access mdp5_global_state. This will replace the existing mdp5_state struct (which subclasses drm_atomic_state) and the funcs around it. These will be removed later once we mdp5_global_state is put to use everywhere. Signed-off-by: Archit Taneja Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c | 79 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h | 24 ++ 2 files changed, 103 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 7ad0560dbc9f..0f314c1f3e8a 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -106,6 +106,79 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state) swap(to_kms_state(state)->state, mdp5_kms->state); } +/* Global/shared object state funcs */ + +/* + * This is a helper that returns the private state currently in operation. + * Note that this would return the "old_state" if called in the atomic check + * path, and the "new_state" after the atomic swap has been done. + */ +struct mdp5_global_state * +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms) +{ + return to_mdp5_global_state(mdp5_kms->glob_state.state); +} + +/* + * This acquires the modeset lock set aside for global state, creates + * a new duplicated private object state. + */ +struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s) +{ + struct msm_drm_private *priv = s->dev->dev_private; + struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); + struct drm_private_state *priv_state; + + priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_state); + if (IS_ERR(priv_state)) + return ERR_CAST(priv_state); + + return to_mdp5_global_state(priv_state); +} + +static struct drm_private_state * +mdp5_global_duplicate_state(struct drm_private_obj *obj) +{ + struct mdp5_global_state *state; + + state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL); + if (!state) + return NULL; + + __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base); + + return &state->base; +} + +static void mdp5_global_destroy_state(struct drm_private_obj *obj, + struct drm_private_state *state) +{ + struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state); + + kfree(mdp5_state); +} + +static const struct drm_private_state_funcs mdp5_global_state_funcs = { + .atomic_duplicate_state = mdp5_global_duplicate_state, + .atomic_destroy_state = mdp5_global_destroy_state, +}; + +static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms) +{ + struct mdp5_global_state *state; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (!state) + return -ENOMEM; + + state->mdp5_kms = mdp5_kms; + + drm_atomic_private_obj_init(&mdp5_kms->glob_state, + &state->base, + &mdp5_global_state_funcs); + return 0; +} + static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) { struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); @@ -779,6 +852,8 @@ static void mdp5_destroy(struct platform_device *pdev) if (mdp5_kms->rpm_enabled) pm_runtime_disable(&pdev->dev); + drm_atomic_private_obj_fini(&mdp5_kms->glob_state); + kfree(mdp5_kms->state); } @@ -939,6 +1014,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) goto fail; } + ret = mdp5_global_obj_init(mdp5_kms); + if (ret) + goto fail; + mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5"); if (IS_ERR(mdp5_kms->mmio)) { ret = PTR_ERR(mdp5_kms->mmio); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h index 312e6a47dff8..1c70aac20a98 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h @@ -57,6 +57,12 @@ struct mdp5_kms { struct mdp5_state *state; struct drm_modeset_lock state_lock; + /* +* Global private object state, Do not access directly, use +* mdp5_global_get_state() +*/ + struct drm_private_obj glob_state; + struct mdp5_smp *smp; struct mdp5_ctl_manager *ctlm; @@ -97,6 +103,24 @@ struct md
[PATCH 1/4] drm/atomic: integrate modeset lock with private objects
Follow the same pattern of locking as with other state objects. This avoids boilerplate in the driver. Signed-off-by: Rob Clark --- drivers/gpu/drm/drm_atomic.c | 9 - include/drm/drm_atomic.h | 5 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index fc8c4da409ff..004e621ab307 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1078,6 +1078,8 @@ drm_atomic_private_obj_init(struct drm_private_obj *obj, { memset(obj, 0, sizeof(*obj)); + drm_modeset_lock_init(&obj->lock); + obj->state = state; obj->funcs = funcs; } @@ -1093,6 +1095,7 @@ void drm_atomic_private_obj_fini(struct drm_private_obj *obj) { obj->funcs->atomic_destroy_state(obj, obj->state); + drm_modeset_lock_fini(&obj->lock); } EXPORT_SYMBOL(drm_atomic_private_obj_fini); @@ -1113,7 +1116,7 @@ struct drm_private_state * drm_atomic_get_private_obj_state(struct drm_atomic_state *state, struct drm_private_obj *obj) { - int index, num_objs, i; + int index, num_objs, i, ret; size_t size; struct __drm_private_objs_state *arr; struct drm_private_state *obj_state; @@ -1122,6 +1125,10 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state, if (obj == state->private_objs[i].ptr) return state->private_objs[i].state; + ret = drm_modeset_lock(&obj->lock, state->acquire_ctx); + if (ret) + return ERR_PTR(ret); + num_objs = state->num_private_objs + 1; size = sizeof(*state->private_objs) * num_objs; arr = krealloc(state->private_objs, size, GFP_KERNEL); diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index 09076a625637..9ae53b73c9d2 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -218,6 +218,11 @@ struct drm_private_state_funcs { * &drm_modeset_lock is required to duplicate and update this object's state. */ struct drm_private_obj { + /** +* @lock: Modeset lock to protect the state object. +*/ + struct drm_modeset_lock lock; + /** * @state: Current atomic state for this driver private object. */ -- 2.14.3
Re: [PATCH 2/2] perf, tools, stat: Reset ids counter when retrying events
On Wed, Feb 21, 2018 at 11:33:37AM -0300, Arnaldo Carvalho de Melo wrote: > Em Wed, Feb 21, 2018 at 03:31:17PM +0100, Jiri Olsa escreveu: > > On Thu, Oct 05, 2017 at 07:00:29PM -0700, Andi Kleen wrote: > > > From: Andi Kleen > > > > ouch, sry for overlooking this > > > > > > > > perf stat can retry opening events. After opening an file descriptor > > > it adds the ids to the ecsel. Each event keeps a running > > > count of ids. When we decide to close an evsel and retry > > > with a different configuration this count needs to be reset, > > > otherwise it can overflow the buffer. > > > > how can this happen? we call store_counter_ids at the > > end of the loop, when the evsel is all done and can't > > be reconfigured > > Yeah, I couldn't figure out the exact sequence, but I think that we need > to reset those hash tables when doing a perf_evlist__close(), no? I.e. > when we open we may get new ids, so need to rehash? yes, I think we should reset it any time the event is closed I'll check your changes jirka
[PATCH 4.9 07/77] ext4: fix a race in the ext4 shutdown path
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Harshad Shirwadkar commit abbc3f9395c76d554a9ed27d4b1ebfb5d9b0e4ca upstream. This patch fixes a race between the shutdown path and bio completion handling. In the ext4 direct io path with async io, after submitting a bio to the block layer, if journal starting fails, ext4_direct_IO_write() would bail out pretending that the IO failed. The caller would have had no way of knowing whether or not the IO was successfully submitted. So instead, we return -EIOCBQUEUED in this case. Now, the caller knows that the IO was submitted. The bio completion handler takes care of the error. Tested: Ran the shutdown xfstest test 461 in loop for over 2 hours across 4 machines resulting in over 400 runs. Verified that the race didn't occur. Usually the race was seen in about 20-30 iterations. Signed-off-by: Harshad Shirwadkar Signed-off-by: Theodore Ts'o Cc: sta...@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- fs/ext4/inode.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3526,10 +3526,18 @@ static ssize_t ext4_direct_IO_write(stru /* Credits for sb + inode write */ handle = ext4_journal_start(inode, EXT4_HT_INODE, 2); if (IS_ERR(handle)) { - /* This is really bad luck. We've written the data -* but cannot extend i_size. Bail out and pretend -* the write failed... */ - ret = PTR_ERR(handle); + /* +* We wrote the data but cannot extend +* i_size. Bail out. In async io case, we do +* not return error here because we have +* already submmitted the corresponding +* bio. Returning error here makes the caller +* think that this IO is done and failed +* resulting in race with bio's completion +* handler. +*/ + if (!ret) + ret = PTR_ERR(handle); if (inode->i_nlink) ext4_orphan_del(NULL, inode);
[PATCH 4.9 26/77] ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Kirill Marinushkin commit 447cae58cecd69392b74a4a42cd0ab9cabd816af upstream. The layout of the UAC2 Control request and response varies depending on the request type. With the current implementation, only the Layout 2 Parameter Block (with the 2-byte sized RANGE attribute) is handled properly. For the Control requests with the 1-byte sized RANGE attribute (Bass Control, Mid Control, Tremble Control), the response is parsed incorrectly. This commit: * fixes the wLength field value in the request * fixes parsing the range values from the response Fixes: 23caaf19b11e ("ALSA: usb-mixer: Add support for Audio Class v2.0") Signed-off-by: Kirill Marinushkin Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/usb/mixer.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -344,17 +344,20 @@ static int get_ctl_value_v2(struct usb_m int validx, int *value_ret) { struct snd_usb_audio *chip = cval->head.mixer->chip; - unsigned char buf[4 + 3 * sizeof(__u32)]; /* enough space for one range */ + /* enough space for one range */ + unsigned char buf[sizeof(__u16) + 3 * sizeof(__u32)]; unsigned char *val; - int idx = 0, ret, size; + int idx = 0, ret, val_size, size; __u8 bRequest; + val_size = uac2_ctl_value_size(cval->val_type); + if (request == UAC_GET_CUR) { bRequest = UAC2_CS_CUR; - size = uac2_ctl_value_size(cval->val_type); + size = val_size; } else { bRequest = UAC2_CS_RANGE; - size = sizeof(buf); + size = sizeof(__u16) + 3 * val_size; } memset(buf, 0, sizeof(buf)); @@ -387,16 +390,17 @@ error: val = buf + sizeof(__u16); break; case UAC_GET_MAX: - val = buf + sizeof(__u16) * 2; + val = buf + sizeof(__u16) + val_size; break; case UAC_GET_RES: - val = buf + sizeof(__u16) * 3; + val = buf + sizeof(__u16) + val_size * 2; break; default: return -EINVAL; } - *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(val, sizeof(__u16))); + *value_ret = convert_signed_value(cval, + snd_usb_combine_bytes(val, val_size)); return 0; }
[PATCH] crypto: ccp: add check to get PSP master only when PSP is detected
Paulian reported the below kernel crash on Ryzen 5 system: BUG: unable to handle kernel NULL pointer dereference at 0073 RIP: 0010:.LC0+0x41f/0xa00 RSP: 0018:a9968003bdd0 EFLAGS: 00010002 RAX: b113b130 RBX: RCX: 05a7 RDX: 00ff RSI: 8b46dee651a0 RDI: b1bd617c RBP: 0246 R08: 000251a0 R09: R10: d81f11a38200 R11: 8b52e8e0a161 R12: b19db220 R13: 0007 R14: b17e4888 R15: 5dccd7affc30a31e FS: () GS:8b46dee4() knlGS: CR2: 0073 CR3: 80128120a000 CR4: 003406e0 Call Trace: ? sp_get_psp_master_device+0x56/0x80 ? map_properties+0x540/0x540 ? psp_pci_init+0x20/0xe0 ? map_properties+0x540/0x540 ? sp_mod_init+0x16/0x1a ? do_one_initcall+0x4b/0x190 ? kernel_init_freeable+0x19b/0x23c ? rest_init+0xb0/0xb0 ? kernel_init+0xa/0x100 ? ret_from_fork+0x22/0x40 Since Ryzen does not support PSP/SEV firmware hence i->psp_data will NULL in all sp instances. In those cases, 'i' will point to the list head after list_for_each_entry(). Dereferencing the head will cause kernel crash. Add check to call get master device only when PSP/SEV is detected. Reported-by: Paulian Bogdan Marinca Cc: Borislav Petkov Cc: Tom Lendacky CC: Gary R Hook Cc: linux-kernel@vger.kernel.org Signed-off-by: Brijesh Singh --- drivers/crypto/ccp/psp-dev.c | 1 + drivers/crypto/ccp/sp-dev.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c index b3afb6cc9d72..b342210e582a 100644 --- a/drivers/crypto/ccp/psp-dev.c +++ b/drivers/crypto/ccp/psp-dev.c @@ -677,6 +677,7 @@ static int sev_misc_init(struct psp_device *psp) static int sev_init(struct psp_device *psp) { + return 1; /* Check if device supports SEV feature */ if (!(ioread32(psp->io_regs + PSP_FEATURE_REG) & 1)) { dev_dbg(psp->dev, "device does not support SEV\n"); diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index eb0da6572720..e0459002eb71 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -252,12 +252,12 @@ struct sp_device *sp_get_psp_master_device(void) goto unlock; list_for_each_entry(i, &sp_units, entry) { - if (i->psp_data) + if (i->psp_data && i->get_psp_master_device) { + ret = i->get_psp_master_device(); break; + } } - if (i->get_psp_master_device) - ret = i->get_psp_master_device(); unlock: write_unlock_irqrestore(&sp_unit_lock, flags); return ret; -- 2.14.3
[PATCH 4.9 28/77] ALSA: hda/realtek: PCI quirk for Fujitsu U7x7
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Jan-Marek Glogowski commit fdcc968a3b290407bcba9d4c90e2fba6d8d928f1 upstream. These laptops have a combined jack to attach headsets, the U727 on the left, the U757 on the right, but a headsets microphone doesn't work. Using hdajacksensetest I found that pin 0x19 changed the present state when plugging the headset, in addition to 0x21, but didn't have the correct configuration (shown as "Not connected"). So this sets the configuration to the same values as the headphone pin 0x21 except for the device type microphone, which makes it work correctly. With the patch the configured pins for U727 are Pin 0x12 (Internal Mic, Mobile-In): present = No Pin 0x14 (Internal Speaker): present = No Pin 0x19 (Black Mic, Left side): present = No Pin 0x1d (Internal Aux): present = No Pin 0x21 (Black Headphone, Left side): present = No Signed-off-by: Jan-Marek Glogowski Cc: Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- sound/pci/hda/patch_realtek.c | 19 +++ 1 file changed, 19 insertions(+) --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3130,6 +3130,19 @@ static void alc269_fixup_pincfg_no_hp_to spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; } +static void alc269_fixup_pincfg_U7x7_headset_mic(struct hda_codec *codec, +const struct hda_fixup *fix, +int action) +{ + unsigned int cfg_headphone = snd_hda_codec_get_pincfg(codec, 0x21); + unsigned int cfg_headset_mic = snd_hda_codec_get_pincfg(codec, 0x19); + + if (cfg_headphone && cfg_headset_mic == 0x41f0) + snd_hda_codec_set_pincfg(codec, 0x19, + (cfg_headphone & ~AC_DEFCFG_DEVICE) | + (AC_JACK_MIC_IN << AC_DEFCFG_DEVICE_SHIFT)); +} + static void alc269_fixup_hweq(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -4819,6 +4832,7 @@ enum { ALC269_FIXUP_LIFEBOOK_EXTMIC, ALC269_FIXUP_LIFEBOOK_HP_PIN, ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT, + ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC, ALC269_FIXUP_AMIC, ALC269_FIXUP_DMIC, ALC269VB_FIXUP_AMIC, @@ -5010,6 +5024,10 @@ static const struct hda_fixup alc269_fix .type = HDA_FIXUP_FUNC, .v.func = alc269_fixup_pincfg_no_hp_to_lineout, }, + [ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc269_fixup_pincfg_U7x7_headset_mic, + }, [ALC269_FIXUP_AMIC] = { .type = HDA_FIXUP_PINS, .v.pins = (const struct hda_pintbl[]) { @@ -5733,6 +5751,7 @@ static const struct snd_pci_quirk alc269 SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT), SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN), SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN), + SND_PCI_QUIRK(0x10cf, 0x1629, "Lifebook U7x7", ALC255_FIXUP_LIFEBOOK_U7x7_HEADSET_MIC), SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC), SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
[PATCH 4.9 33/77] dm: correctly handle chained bios in dec_pending()
4.9-stable review patch. If anyone has any objections, please let me know. -- From: NeilBrown commit 8dd601fa8317243be887458c49f6c29c2f3d719f upstream. dec_pending() is given an error status (possibly 0) to be recorded against a bio. It can be called several times on the one 'struct dm_io', and it is careful to only assign a non-zero error to io->status. However when it then assigned io->status to bio->bi_status, it is not careful and could overwrite a genuine error status with 0. This can happen when chained bios are in use. If a bio is chained beneath the bio that this dm_io is handling, the child bio might complete and set bio->bi_status before the dm_io completes. This has been possible since chained bios were introduced in 3.14, and has become a lot easier to trigger with commit 18a25da84354 ("dm: ensure bio submission follows a depth-first tree walk") as that commit caused dm to start using chained bios itself. A particular failure mode is that if a bio spans an 'error' target and a working target, the 'error' fragment will complete instantly and set the ->bi_status, and the other fragment will normally complete a little later, and will clear ->bi_status. The fix is simply to only assign io_error to bio->bi_status when io_error is not zero. Reported-and-tested-by: Milan Broz Cc: sta...@vger.kernel.org (v3.14+) Signed-off-by: NeilBrown Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -809,7 +809,8 @@ static void dec_pending(struct dm_io *io } else { /* done with normal IO or empty flush */ trace_block_bio_complete(md->queue, bio, io_error); - bio->bi_error = io_error; + if (io_error) + bio->bi_error = io_error; bio_endio(bio); } }
[PATCH 4.9 34/77] powerpc: fix build errors in stable tree
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Nicholas Piggin This is just the first chunk of commit 222f20f140623ef6033491d0103ee0875fe87d35 upstream. to fix a build error in the powerpc tree due to other backports happening (and this full patch not being backported). Reported-by: Guenter Roeck Reported-by: Yves-Alexis Perez Cc: Nicholas Piggin Cc: Michael Ellerman Cc: Yves-Alexis Perez Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/kernel/entry_64.S |5 + 1 file changed, 5 insertions(+) --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -39,6 +39,11 @@ #include #include #include +#ifdef CONFIG_PPC_BOOK3S +#include +#else +#include +#endif /* * System calls.
[PATCH 4.9 35/77] IB/qib: Fix comparison error with qperf compare/swap test
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Mike Marciniszyn commit 87b3524cb5058fdc7c2afdb92bdb2e079661ddc4 upstream. This failure exists with qib: ver_rc_compare_swap: mismatch, sequence 2, expected 123456789abcdef, got 0 The request builder was using the incorrect inlines to build the request header resulting in incorrect data in the atomic header. Fix by using the appropriate inlines to create the request. Fixes: 261a4351844b ("IB/qib,IB/hfi: Use core common header file") Reviewed-by: Michael J. Ruhl Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/qib/qib_rc.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- a/drivers/infiniband/hw/qib/qib_rc.c +++ b/drivers/infiniband/hw/qib/qib_rc.c @@ -443,13 +443,13 @@ no_flow_control: qp->s_state = OP(COMPARE_SWAP); put_ib_ateth_swap(wqe->atomic_wr.swap, &ohdr->u.atomic_eth); - put_ib_ateth_swap(wqe->atomic_wr.compare_add, - &ohdr->u.atomic_eth); + put_ib_ateth_compare(wqe->atomic_wr.compare_add, +&ohdr->u.atomic_eth); } else { qp->s_state = OP(FETCH_ADD); put_ib_ateth_swap(wqe->atomic_wr.compare_add, &ohdr->u.atomic_eth); - put_ib_ateth_swap(0, &ohdr->u.atomic_eth); + put_ib_ateth_compare(0, &ohdr->u.atomic_eth); } put_ib_ateth_vaddr(wqe->atomic_wr.remote_addr, &ohdr->u.atomic_eth);
[PATCH 4.9 36/77] IB/mlx4: Fix incorrectly releasing steerable UD QPs when have only ETH ports
4.9-stable review patch. If anyone has any objections, please let me know. -- From: Jack Morgenstein commit 852f6927594d0d3e8632c889b2ab38cbc46476ad upstream. Allocating steerable UD QPs depends on having at least one IB port, while releasing those QPs does not. As a result, when there are only ETH ports, the IB (RoCE) driver requests releasing a qp range whose base qp is zero, with qp count zero. When SR-IOV is enabled, and the VF driver is running on a VM over a hypervisor which treats such qp release calls as errors (rather than NOPs), we see lines in the VM message log like: mlx4_core 0002:00:02.0: Failed to release qp range base:0 cnt:0 Fix this by adding a check for a zero count in mlx4_release_qp_range() (which thus treats releasing 0 qps as a nop), and eliminating the check for device managed flow steering when releasing steerable UD QPs. (Freeing ib_uc_qpns_bitmap unconditionally is also OK, since it remains NULL when steerable UD QPs are not allocated). Fixes: 4196670be786 ("IB/mlx4: Don't allocate range of steerable UD QPs for Ethernet-only device") Signed-off-by: Jack Morgenstein Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/mlx4/main.c | 13 + drivers/net/ethernet/mellanox/mlx4/qp.c |3 +++ 2 files changed, 8 insertions(+), 8 deletions(-) --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -2928,9 +2928,8 @@ err_steer_free_bitmap: kfree(ibdev->ib_uc_qpns_bitmap); err_steer_qp_release: - if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) - mlx4_qp_release_range(dev, ibdev->steer_qpn_base, - ibdev->steer_qpn_count); + mlx4_qp_release_range(dev, ibdev->steer_qpn_base, + ibdev->steer_qpn_count); err_counter: for (i = 0; i < ibdev->num_ports; ++i) mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]); @@ -3035,11 +3034,9 @@ static void mlx4_ib_remove(struct mlx4_d ibdev->iboe.nb.notifier_call = NULL; } - if (ibdev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) { - mlx4_qp_release_range(dev, ibdev->steer_qpn_base, - ibdev->steer_qpn_count); - kfree(ibdev->ib_uc_qpns_bitmap); - } + mlx4_qp_release_range(dev, ibdev->steer_qpn_base, + ibdev->steer_qpn_count); + kfree(ibdev->ib_uc_qpns_bitmap); iounmap(ibdev->uar_map); for (p = 0; p < ibdev->num_ports; ++p) --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -286,6 +286,9 @@ void mlx4_qp_release_range(struct mlx4_d u64 in_param = 0; int err; + if (!cnt) + return; + if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, base_qpn); set_param_h(&in_param, cnt);