Re: [PATCH 1/5] arm: sunxi: add support for V3s SoC
1;4601;0c On Thu, Jan 12, 2017 at 03:40:32AM +0800, Icenowy Zheng wrote: > > > 11.01.2017, 02:09, "Maxime Ripard" : > > On Tue, Jan 03, 2017 at 11:16:25PM +0800, Icenowy Zheng wrote: > >> Allwinner V3s is a low-end single-core Cortex-A7 SoC, with 64MB > >> integrated DRAM, and several peripherals. > >> > >> Signed-off-by: Icenowy Zheng > >> --- > >> Documentation/arm/sunxi/README | 4 > >> arch/arm/mach-sunxi/sunxi.c | 1 + > >> 2 files changed, 5 insertions(+) > >> > >> diff --git a/Documentation/arm/sunxi/README > >> b/Documentation/arm/sunxi/README > >> index cd0243302bc1..91ec8f2055be 100644 > >> --- a/Documentation/arm/sunxi/README > >> +++ b/Documentation/arm/sunxi/README > >> @@ -67,6 +67,10 @@ SunXi family > >> + Datasheet > >> http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf > >> > >> + - Allwinner V3s (sun8i) > >> + + Datasheet > >> + > >> https://www.goprawn.com/forum/allwinner-cams/783-allwinner-v3s-soc-datasheet > >> + > > > > Please don't put random links in there, but at least something that we > > know will be there in a couple of weeks/monthes/years > > Is http://linux-sunxi.org/File:Allwinner_V3s_Datasheet_V1.0.pdf acceptable? It's much better, yes. Thanks! Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH v2] ARM64: dts: meson-gxbb-odroidc2: Disable SCPI DVFS
Hi Neil, (adding Brian Kim, one of the Hardkernel developers to this conversation) On Fri, Jan 6, 2017 at 9:04 AM, Neil Armstrong wrote: > The current hardware is not able to run with all cores enabled at a > cluster frequency superior at 1536MHz. > But the currently shipped u-boot for the platform still reports an OPP > table with possible DVFS frequency up to 2GHz, and will not change since > the off-tree linux tree supports limiting the OPPs with a kernel parameter. > A recent u-boot change reports the boot-time DVFS around 100MHz and > the default performance cpufreq governor sets the maximum frequency. > Previous version of u-boot reported to be already at the max OPP and > left the OPP as is. > Nevertheless, other governors like ondemand could setup the max frequency > and make the system crash. > > This patch disables the DVFS clock and disables cpufreq. I don't have any Odroid-C2 board, but having to live without cpufreq sounds bad for the Odroid-C2 users. What would we expect from a kernel perspective (maybe the Hardkernel guys would adjust their u-boot instead of us adjusting to the behavior of one specific device? one solution that I could think of involves the "maxcpus" kernel parameter (see [0]), if this is not set u-boot should report a max CPU frequency of 1536MHz (= max frequency for 4 active cores). Based on the "maxcpus" value additional frequencies can be unlocked (this could be step-by-step if there are different frequencies for one core/two cores/etc.). However, I'd like to hear other opinions as well. Regards, Martin [0] http://lxr.free-electrons.com/source/Documentation/kernel-parameters.txt?v=4.8#L2163
Re: [PATCHv7 00/11] CONFIG_DEBUG_VIRTUAL for arm64
On Tue, Jan 10, 2017 at 01:35:39PM -0800, Laura Abbott wrote: > This is v7 of the patches to add CONFIG_DEBUG_VIRTUAL for arm64. This is > a simple reordering of patches from v6 per request of Will Deacon for ease > of merging support for arm which depends on this series. > > Laura Abbott (11): > lib/Kconfig.debug: Add ARCH_HAS_DEBUG_VIRTUAL > mm/cma: Cleanup highmem check > mm: Introduce lm_alias > kexec: Switch to __pa_symbol > mm/kasan: Switch to using __pa_symbol and lm_alias > mm/usercopy: Switch to using lm_alias > drivers: firmware: psci: Use __pa_symbol for kernel symbol > arm64: Move some macros under #ifndef __ASSEMBLY__ > arm64: Add cast for virt_to_pfn > arm64: Use __pa_symbol for kernel symbols > arm64: Add support for CONFIG_DEBUG_VIRTUAL I've pushed this into linux-next and, assuming it survives the autobuilders etc I'll co-ordinate with Russell to get the common parts pulled into the ARM tree too (so he can take Florian's series). They're currently split out on the arm64 for-next/debug-virtual branch. Thanks! Will
[PATCH v5] DAX: enable iostat for read/write
DAX IO path does not support iostat, but its metadata IO path does. Therefore, iostat shows metadata IO statistics only, which has been confusing to users. Add iostat support to the DAX read/write path. Note, iostat still does not support the DAX mmap path as it allows user applications to access directly. Signed-off-by: Toshi Kani Cc: Andrew Morton Cc: Dan Williams Cc: Alexander Viro Cc: Dave Chinner Cc: Ross Zwisler Cc: Joe Perches --- v5: - Add a flag in case 'start' is 0 after 'jiffies' rolls over. (Dan Williams) - Fix a signed/unsigned conversion. (Joe Perches) --- fs/dax.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/fs/dax.c b/fs/dax.c index 5c74f60..a3e406a 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, { struct address_space *mapping = iocb->ki_filp->f_mapping; struct inode *inode = mapping->host; + struct gendisk *disk = inode->i_sb->s_bdev->bd_disk; loff_t pos = iocb->ki_pos, ret = 0, done = 0; unsigned flags = 0; + unsigned long start = 0; + int do_acct = blk_queue_io_stat(disk->queue); if (iov_iter_rw(iter) == WRITE) flags |= IOMAP_WRITE; + if (do_acct) { + sector_t sec = iov_iter_count(iter) >> 9; + + start = jiffies; + generic_start_io_acct(iov_iter_rw(iter), + min_t(unsigned long, 1, sec), + &disk->part0); + } + while (iov_iter_count(iter)) { ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops, iter, dax_iomap_actor); @@ -1073,6 +1085,9 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, done += ret; } + if (do_acct) + generic_end_io_acct(iov_iter_rw(iter), &disk->part0, start); + iocb->ki_pos += done; return done ? done : ret; }
Re: [PATCH v8 2/2] tpm: add securityfs support for TPM 2.0 firmware event log
On Wed, Jan 11, 2017 at 02:54:22AM -0500, Nayna Jain wrote: > Unlike the device driver support for TPM 1.2, the TPM 2.0 does > not support the securityfs pseudo files for displaying the > firmware event log. > > This patch enables support for providing the TPM 2.0 event log in > binary form. TPM 2.0 event log supports a crypto agile format that > records multiple digests, which is different from TPM 1.2. This > patch enables the tpm_bios_log_setup for TPM 2.0 and adds the > event log parser which understand the TPM 2.0 crypto agile format. > > Signed-off-by: Nayna Jain Overally looks good but I cannot test this. /Jarkko > --- > drivers/char/tpm/Makefile | 2 +- > .../char/tpm/{tpm_eventlog.c => tpm1_eventlog.c} | 35 ++-- > drivers/char/tpm/tpm2_eventlog.c | 203 > + > drivers/char/tpm/tpm_acpi.c| 3 + > drivers/char/tpm/tpm_eventlog.h| 63 +++ > 5 files changed, 291 insertions(+), 15 deletions(-) > rename drivers/char/tpm/{tpm_eventlog.c => tpm1_eventlog.c} (95%) > create mode 100644 drivers/char/tpm/tpm2_eventlog.c > > diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile > index a05b1eb..3d386a8 100644 > --- a/drivers/char/tpm/Makefile > +++ b/drivers/char/tpm/Makefile > @@ -3,7 +3,7 @@ > # > obj-$(CONFIG_TCG_TPM) += tpm.o > tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ > - tpm_eventlog.o > + tpm1_eventlog.o tpm2_eventlog.o > tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o > tpm-$(CONFIG_OF) += tpm_of.o > obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o > diff --git a/drivers/char/tpm/tpm_eventlog.c > b/drivers/char/tpm/tpm1_eventlog.c > similarity index 95% > rename from drivers/char/tpm/tpm_eventlog.c > rename to drivers/char/tpm/tpm1_eventlog.c > index 11bb113..9a8605e 100644 > --- a/drivers/char/tpm/tpm_eventlog.c > +++ b/drivers/char/tpm/tpm1_eventlog.c > @@ -390,9 +390,6 @@ int tpm_bios_log_setup(struct tpm_chip *chip) > unsigned int cnt; > int rc = 0; > > - if (chip->flags & TPM_CHIP_FLAG_TPM2) > - return 0; > - > rc = tpm_read_log(chip); > if (rc) > return rc; > @@ -407,7 +404,13 @@ int tpm_bios_log_setup(struct tpm_chip *chip) > cnt++; > > chip->bin_log_seqops.chip = chip; > - chip->bin_log_seqops.seqops = &tpm_binary_b_measurements_seqops; > + if (chip->flags & TPM_CHIP_FLAG_TPM2) > + chip->bin_log_seqops.seqops = > + &tpm2_binary_b_measurements_seqops; > + else > + chip->bin_log_seqops.seqops = > + &tpm_binary_b_measurements_seqops; > + > > chip->bios_dir[cnt] = > securityfs_create_file("binary_bios_measurements", > @@ -418,17 +421,21 @@ int tpm_bios_log_setup(struct tpm_chip *chip) > goto err; > cnt++; > > - chip->ascii_log_seqops.chip = chip; > - chip->ascii_log_seqops.seqops = &tpm_ascii_b_measurements_seqops; > + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { > > - chip->bios_dir[cnt] = > - securityfs_create_file("ascii_bios_measurements", > -0440, chip->bios_dir[0], > -(void *)&chip->ascii_log_seqops, > -&tpm_bios_measurements_ops); > - if (IS_ERR(chip->bios_dir[cnt])) > - goto err; > - cnt++; > + chip->ascii_log_seqops.chip = chip; > + chip->ascii_log_seqops.seqops = > + &tpm_ascii_b_measurements_seqops; > + > + chip->bios_dir[cnt] = > + securityfs_create_file("ascii_bios_measurements", > +0440, chip->bios_dir[0], > +(void *)&chip->ascii_log_seqops, > +&tpm_bios_measurements_ops); > + if (IS_ERR(chip->bios_dir[cnt])) > + goto err; > + cnt++; > + } > > return 0; > > diff --git a/drivers/char/tpm/tpm2_eventlog.c > b/drivers/char/tpm/tpm2_eventlog.c > new file mode 100644 > index 000..1063b09 > --- /dev/null > +++ b/drivers/char/tpm/tpm2_eventlog.c > @@ -0,0 +1,203 @@ > +/* > + * Copyright (C) 2016 IBM Corporation > + * > + * Authors: > + * Nayna Jain > + * > + * Access to TPM 2.0 event log as written by Firmware. > + * It assumes that writer of event log has followed TCG Specification > + * for Family "2.0" and written the event data in little endian. > + * With that, it doesn't need any endian conversion for structure > + * content. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > + >
Re: [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU
On Fri, Jan 13, 2017 at 01:31:41AM +0800, Icenowy Zheng wrote: > > 2017年1月13日 01:19于 Maxime Ripard 写道: > > > > On Thu, Jan 12, 2017 at 03:44:53AM +0800, Icenowy Zheng wrote: > > > > > > > > > 12.01.2017, 03:40, "Icenowy Zheng" : > > > > 11.01.2017, 02:10, "Maxime Ripard" : > > > >> On Tue, Jan 03, 2017 at 11:16:26PM +0800, Icenowy Zheng wrote: > > > >>> V3s has a similar but cut-down CCU to H3. > > > >>> > > > >>> Add support for it. > > > >>> > > > >>> Signed-off-by: Icenowy Zheng > > > >> > > > >> It looks like there's nothing different but the clocks that you > > > >> register with the H3, please just use the H3 driver. > > > > > > > > Nope. > > > > > > > > It has a different PLL (PLL_ISP) at different address, and some > > > > different muxes. > > > > > > Forgot to mention the missing of PLL_DE and related misses. > > > > Those are not conflicting, it's just a slightly different set of > > clocks. > > If saying so, we can have only one ccu driver, and make every ccu > register different set ;-) > > V3s itself is a totally different SoC with H3. > > The relationship of V3s and H3 can be farther than the relationship > of A33 and H3😃 A33 and H3 are an entirely different story. The H3 and A33 have conflicting clocks (ie same clocks with different parameters). This is not your case. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH v2 2/2] Support for DW CSI-2 Host IPK
Hi Hans, Thank you for your feedback. On 1/11/2017 11:54 AM, Hans Verkuil wrote: > Hi Ramiro, > > See my review comments below: > > On 12/12/16 16:00, Ramiro Oliveira wrote: >> Add support for the DesignWare CSI-2 Host IP Prototyping Kit >> >> Signed-off-by: Ramiro Oliveira [snip] >> +static int >> +dw_mipi_csi_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config >> *cfg, >> +struct v4l2_subdev_format *fmt) >> +{ >> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd); >> +struct mipi_fmt const *dev_fmt; >> +struct v4l2_mbus_framefmt *mf; >> +unsigned int i = 0; >> +const struct v4l2_bt_timings *bt_r = &v4l2_dv_timings_presets[0].bt; >> + >> +mf = __dw_mipi_csi_get_format(dev, cfg, fmt->which); >> + >> +dev_fmt = dw_mipi_csi_try_format(&fmt->format); >> +if (dev_fmt) { >> +*mf = fmt->format; >> +if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) >> +dev->fmt = dev_fmt; >> +dw_mipi_csi_set_ipi_fmt(dev); >> +} >> +while (v4l2_dv_timings_presets[i].bt.width) { >> +const struct v4l2_bt_timings *bt = >> +&v4l2_dv_timings_presets[i].bt; >> +if (mf->width == bt->width && mf->height == bt->width) { >> +__dw_mipi_csi_fill_timings(dev, bt); >> +return 0; >> +} >> +i++; >> +} >> + >> +__dw_mipi_csi_fill_timings(dev, bt_r); > > This code is weird. The video source can be either from a sensor or from an > HDMI input, right? > > But if it is from a sensor, then using v4l2_dv_timings_presets since that's > for > an HDMI input. Sensors will typically not follow these preset timings. > > For HDMI input I expect that this driver supports the s_dv_timings op and will > just use the timings set there and override the width/height in > v4l2_subdev_format. > > For sensors I am actually not quite certain how this is done. I've CC-ed > Sakari > since he'll know. But let us know first whether it is indeed the intention > that > this should also work with a sensor. > Actually the video source, at the moment, can only be from a sensor. I'm using v4l2_dv_timings_presets as a reference since we usually use this setup with a Test Equipment in which we can configure every parameter. I'll wait for Sakari to answer, and change it to what he recommends. >> +return 0; >> + >> +} >> + >> +static int >> +dw_mipi_csi_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config >> *cfg, >> +struct v4l2_subdev_format *fmt) >> +{ >> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd); >> +struct v4l2_mbus_framefmt *mf; >> + >> +mf = __dw_mipi_csi_get_format(dev, cfg, fmt->which); >> +if (!mf) >> +return -EINVAL; >> + >> +mutex_lock(&dev->lock); >> +fmt->format = *mf; >> +mutex_unlock(&dev->lock); >> +return 0; >> +} >> + >> +static int >> +dw_mipi_csi_s_power(struct v4l2_subdev *sd, int on) >> +{ >> +struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd); >> + >> +if (on) { >> +dw_mipi_csi_hw_stdby(dev); >> +dw_mipi_csi_start(dev); >> +} else { >> +dw_mipi_csi_mask_irq_power_off(dev); >> +} >> + >> +return 0; >> +} >> + >> +static int >> +dw_mipi_csi_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) >> +{ >> +struct v4l2_mbus_framefmt *format = >> +v4l2_subdev_get_try_format(sd, fh->pad, 0); >> + >> +format->colorspace = V4L2_COLORSPACE_SRGB; >> +format->code = dw_mipi_csi_formats[0].code; >> +format->width = MIN_WIDTH; >> +format->height = MIN_HEIGHT; >> +format->field = V4L2_FIELD_NONE; > > Don't do this. Instead implement the init_cfg pad op and initialize this > there. > > You can then drop this function. > I'll do that. >> + >> +return 0; >> +} >> + >> +static const struct v4l2_subdev_internal_ops dw_mipi_csi_sd_internal_ops = { >> +.open = dw_mipi_csi_open, >> +}; >> + >> +static struct v4l2_subdev_core_ops dw_mipi_csi_core_ops = { >> +.s_power = dw_mipi_csi_s_power, >> +}; >> + >> +static struct v4l2_subdev_pad_ops dw_mipi_csi_pad_ops = { >> +.enum_mbus_code = dw_mipi_csi_enum_mbus_code, >> +.get_fmt = dw_mipi_csi_get_fmt, >> +.set_fmt = dw_mipi_csi_set_fmt, >> +}; >> + >> +static struct v4l2_subdev_ops dw_mipi_csi_subdev_ops = { >> +.core = &dw_mipi_csi_core_ops, >> +.pad = &dw_mipi_csi_pad_ops, >> +}; >> + >> +static irqreturn_t >> +dw_mipi_csi_irq1(int irq, void *dev_id) >> +{ >> +struct mipi_csi_dev *csi_dev = dev_id; >> +u32 global_int_status, i_sts; >> +unsigned long flags; >> +struct device *dev = &csi_dev->pdev->dev; >> + >> +global_int_status = dw_mipi_csi_read(csi_dev, R_CSI2_INTERRUPT); >> +spin_lock_irqsave(&csi_dev->slock, flags); >> + >> +if (global_int_status & CSI2_INT_PHY_FATAL) { >> +i_sts = dw_mipi_csi_read(csi_dev, R_CSI2_INT_PHY_FATAL); >> +dev_dbg_ratelimited(dev, "CSI INT PHY FATAL: %08X\n", i_sts); >> +} >> + >> +i
[PATCH RFC v2 5/5] tpm2: expose resource manager via a device link /dev/tpms
From: James Bottomley Currently the Resource Manager (RM) is not exposed to userspace. Make this exposure via a separate device, which can now be opened multiple times because each read/write transaction goes separately via the RM. Concurrency is protected by the chip->tpm_mutex for each read/write transaction separately. The TPM is cleared of all transient objects by the time the mutex is dropped, so there should be no interference between the kernel and userspace. Signed-off-by: James Bottomley --- drivers/char/tpm/Makefile| 2 +- drivers/char/tpm/tpm-chip.c | 54 ++--- drivers/char/tpm/tpm-interface.c | 13 +++-- drivers/char/tpm/tpm.h | 6 +++-- drivers/char/tpm/tpms-dev.c | 57 5 files changed, 124 insertions(+), 8 deletions(-) create mode 100644 drivers/char/tpm/tpms-dev.c diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 13ff5da..e50d768 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_TCG_TPM) += tpm.o tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ -tpm_eventlog.o tpm2-space.o tpm-dev-common.o +tpm_eventlog.o tpm2-space.o tpm-dev-common.o tpms-dev.o tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o tpm-$(CONFIG_OF) += tpm_of.o obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 993b9ae..0d2be04 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -33,6 +33,7 @@ DEFINE_IDR(dev_nums_idr); static DEFINE_MUTEX(idr_lock); struct class *tpm_class; +struct class *tpm_rm_class; dev_t tpm_devt; /** @@ -168,27 +169,40 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, chip->dev_num = rc; device_initialize(&chip->dev); + device_initialize(&chip->devrm); chip->dev.class = tpm_class; chip->dev.release = tpm_dev_release; chip->dev.parent = pdev; chip->dev.groups = chip->groups; + chip->devrm.parent = pdev; + chip->devrm.class = tpm_rm_class; + if (chip->dev_num == 0) chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); else chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num); + chip->devrm.devt = + MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES); + rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num); if (rc) goto out; + rc = dev_set_name(&chip->devrm, "tpms%d", chip->dev_num); + if (rc) + goto out; if (!pdev) chip->flags |= TPM_CHIP_FLAG_VIRTUAL; cdev_init(&chip->cdev, &tpm_fops); + cdev_init(&chip->cdevrm, &tpm_rm_fops); chip->cdev.owner = THIS_MODULE; + chip->cdevrm.owner = THIS_MODULE; chip->cdev.kobj.parent = &chip->dev.kobj; + chip->cdevrm.kobj.parent = &chip->devrm.kobj; chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!chip->work_space.context_buf) { @@ -200,6 +214,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, out: put_device(&chip->dev); + put_device(&chip->devrm); return ERR_PTR(rc); } EXPORT_SYMBOL_GPL(tpm_chip_alloc); @@ -244,7 +259,7 @@ static int tpm_add_char_device(struct tpm_chip *chip) dev_name(&chip->dev), MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); - return rc; + goto err_1; } rc = device_add(&chip->dev); @@ -254,16 +269,44 @@ static int tpm_add_char_device(struct tpm_chip *chip) dev_name(&chip->dev), MAJOR(chip->dev.devt), MINOR(chip->dev.devt), rc); - cdev_del(&chip->cdev); - return rc; + goto err_2; + } + + if (chip->flags & TPM_CHIP_FLAG_TPM2) + rc = cdev_add(&chip->cdevrm, chip->devrm.devt, 1); + if (rc) { + dev_err(&chip->dev, + "unable to cdev_add() %s, major %d, minor %d, err=%d\n", + dev_name(&chip->devrm), MAJOR(chip->devrm.devt), + MINOR(chip->devrm.devt), rc); + + goto err_3; } + if (chip->flags & TPM_CHIP_FLAG_TPM2) + rc = device_add(&chip->devrm); + if (rc) { + dev_err(&chip->dev, + "unable to device_register() %s, major %d, minor %d, err=%d\n", + dev_name(&chip->devrm), MAJOR(chip->devrm.devt), + MINOR(chip->devrm.devt), rc); + + goto err_4; + } /* Make the chip available. */ mutex_lock(&idr_lock); idr_replace(&dev_nums_idr, chip, chip->dev_num); mutex_unlock(&idr_lock); return rc; + err_4: + cdev_del(&ch
[PATCH RFC v2 4/5] tpm: split out tpm-dev.c into tpm-dev.c and tpm-common-dev.c
From: James Bottomley Signed-off-by: James Bottomley --- drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm-dev-common.c | 145 ++ drivers/char/tpm/tpm-dev.c| 141 drivers/char/tpm/tpm-dev.h| 27 +++ 4 files changed, 187 insertions(+), 128 deletions(-) create mode 100644 drivers/char/tpm/tpm-dev-common.c create mode 100644 drivers/char/tpm/tpm-dev.h diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 251d0ed..13ff5da 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_TCG_TPM) += tpm.o tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ -tpm_eventlog.o tpm2-space.o +tpm_eventlog.o tpm2-space.o tpm-dev-common.o tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o tpm-$(CONFIG_OF) += tpm_of.o obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c new file mode 100644 index 000..0156562 --- /dev/null +++ b/drivers/char/tpm/tpm-dev-common.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2004 IBM Corporation + * Authors: + * Leendert van Doorn + * Dave Safford + * Reiner Sailer + * Kylene Hall + * + * Copyright (C) 2013 Obsidian Research Corp + * Jason Gunthorpe + * + * Device file system interface to the TPM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ +#include +#include +#include "tpm.h" +#include "tpm-dev.h" + +static void user_reader_timeout(unsigned long ptr) +{ + struct file_priv *priv = (struct file_priv *)ptr; + + schedule_work(&priv->work); +} + +static void timeout_work(struct work_struct *work) +{ + struct file_priv *priv = container_of(work, struct file_priv, work); + + mutex_lock(&priv->buffer_mutex); + atomic_set(&priv->data_pending, 0); + memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); + mutex_unlock(&priv->buffer_mutex); +} + +void tpm_common_open(struct file *file, struct tpm_chip *chip, +struct file_priv *priv) +{ + priv->chip = chip; + atomic_set(&priv->data_pending, 0); + mutex_init(&priv->buffer_mutex); + setup_timer(&priv->user_read_timer, user_reader_timeout, + (unsigned long)priv); + INIT_WORK(&priv->work, timeout_work); + + file->private_data = priv; +} + +ssize_t tpm_common_read(struct file *file, char __user *buf, + size_t size, loff_t *off) +{ + struct file_priv *priv = file->private_data; + ssize_t ret_size; + ssize_t orig_ret_size; + int rc; + + del_singleshot_timer_sync(&priv->user_read_timer); + flush_work(&priv->work); + ret_size = atomic_read(&priv->data_pending); + if (ret_size > 0) { /* relay data */ + orig_ret_size = ret_size; + if (size < ret_size) + ret_size = size; + + mutex_lock(&priv->buffer_mutex); + rc = copy_to_user(buf, priv->data_buffer, ret_size); + memset(priv->data_buffer, 0, orig_ret_size); + if (rc) + ret_size = -EFAULT; + + mutex_unlock(&priv->buffer_mutex); + } + + atomic_set(&priv->data_pending, 0); + + return ret_size; +} + +ssize_t tpm_common_write(struct file *file, const char __user *buf, +size_t size, loff_t *off, struct tpm_space *space) +{ + struct file_priv *priv = file->private_data; + size_t in_size = size; + ssize_t out_size; + + /* Cannot perform a write until the read has cleared either via +* tpm_read or a user_read_timer timeout. This also prevents split +* buffered writes from blocking here. +*/ + if (atomic_read(&priv->data_pending) != 0) + return -EBUSY; + + if (in_size > TPM_BUFSIZE) + return -E2BIG; + + mutex_lock(&priv->buffer_mutex); + + if (copy_from_user + (priv->data_buffer, (void __user *) buf, in_size)) { + mutex_unlock(&priv->buffer_mutex); + return -EFAULT; + } + + /* atomic tpm command send and result receive. We only hold the ops +* lock during this period so that the tpm can be unregistered even if +* the char dev is held open. +*/ + if (tpm_try_get_ops(priv->chip)) { + mutex_unlock(&priv->buffer_mutex); + return -EPIPE; + } + out_size = tpm_transmit(priv->chip, space, priv->data_buffer, + sizeof(priv->data_buffer), 0); + + tpm_put_ops(priv->chip); + if (out_size < 0) { + mutex_unlock(&priv->buffer_mutex); +
Applied "spi: davinci: use dma_mapping_error()" to the spi tree
The patch spi: davinci: use dma_mapping_error() has been applied to the spi tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From c5a2a394835f473ae23931eda5066d3771d7b2f8 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 11 Jan 2017 18:18:40 -0800 Subject: [PATCH] spi: davinci: use dma_mapping_error() The correct error checking for dma_map_single() is to use dma_mapping_error(). Signed-off-by: Kevin Hilman Signed-off-by: Mark Brown --- drivers/spi/spi-davinci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index d36c11b73a35..02fb96797ac8 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -646,7 +646,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) buf = t->rx_buf; t->rx_dma = dma_map_single(&spi->dev, buf, t->len, DMA_FROM_DEVICE); - if (!t->rx_dma) { + if (dma_mapping_error(&spi->dev, !t->rx_dma)) { ret = -EFAULT; goto err_rx_map; } @@ -660,7 +660,7 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) buf = (void *)t->tx_buf; t->tx_dma = dma_map_single(&spi->dev, buf, t->len, DMA_TO_DEVICE); - if (!t->tx_dma) { + if (dma_mapping_error(&spi->dev, t->tx_dma)) { ret = -EFAULT; goto err_tx_map; } -- 2.11.0
Re: [PATCH] Input: silead: use msleep() for long delays
Hi, On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote: the delays here are in the 10 to 20ms range so msleep() will do - no need to burden the highres timer subsystem. Signed-off-by: Nicholas Mc Guire --- Problem found by coccinelle script While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems) this seems ok here as the delays are not called frequently (init and reset functions) By the same logic, this is not much of a burden on the high-res timer subsys though. and the uncertainty of 10ms fits the permitted range of the original usleep_ranges(). Either way this patch is fine with me. Regards, Hans Patch was compile tested with: x86_64_defconfig + CONFIG_TOUCHSCREEN_SILEAD=m Patch is against 4.10-rc3 (localversion-next is next-20170112) drivers/input/touchscreen/silead.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index 404830a..3aa885c 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -58,8 +58,7 @@ #define SILEAD_POINT_X_MSB_OFF 0x03 #define SILEAD_TOUCH_ID_MASK 0xF0 -#define SILEAD_CMD_SLEEP_MIN 1 -#define SILEAD_CMD_SLEEP_MAX 2 +#define SILEAD_CMD_SLEEP_MIN 10 /* 10+ ms */ #define SILEAD_POWER_SLEEP 20 #define SILEAD_STARTUP_SLEEP 30 @@ -190,25 +189,25 @@ static int silead_ts_init(struct i2c_client *client) SILEAD_CMD_RESET); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR, data->max_fingers); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK, SILEAD_CLOCK); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, SILEAD_CMD_START); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); return 0; @@ -225,19 +224,19 @@ static int silead_ts_reset(struct i2c_client *client) SILEAD_CMD_RESET); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); error = i2c_smbus_write_byte_data(client, SILEAD_REG_CLOCK, SILEAD_CLOCK); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); error = i2c_smbus_write_byte_data(client, SILEAD_REG_POWER, SILEAD_CMD_START); if (error) goto i2c_write_err; - usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); + msleep(SILEAD_CMD_SLEEP_MIN); return 0;
[PATCH RFC v2 1/5] tpm: validate TPM 2.0 commands
Check for every TPM 2.0 command that the command code is supported and the command buffer has at least the length that can contain the header and the handle area. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-interface.c | 32 - drivers/char/tpm/tpm.h | 27 + drivers/char/tpm/tpm2-cmd.c | 51 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index fecdd3f..0c5aba1 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -328,6 +328,36 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, } EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); +static bool tpm_validate_command(struct tpm_chip *chip, const u8 *cmd, +size_t len) +{ + const struct tpm_input_header *header = (const void *)cmd; + u32 cc; + size_t len_min = TPM_HEADER_SIZE; + u32 attrs; + + if ((len >= len_min) && (chip->flags & TPM_CHIP_FLAG_TPM2) && + chip->nr_commands) { + cc = be32_to_cpu(header->ordinal); + if (!tpm2_find_cc_attrs(chip, cc, &attrs)) { + dev_dbg(&chip->dev, "0x%04x is an invalid command\n", + cc); + return false; + } + len_min += + 4 * ((attrs >> TPM2_CC_ATTR_CHANDLES) & GENMASK(2, 0)); + } + + if (len < len_min) { + dev_dbg(&chip->dev, + "%s: insufficient command length %zu < %zu\n", + __func__, len, len_min); + return false; + } + + return true; +} + /** * tmp_transmit - Internal kernel interface to transmit TPM commands. * @@ -347,7 +377,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, u32 count, ordinal; unsigned long stop; - if (bufsiz < TPM_HEADER_SIZE) + if (!tpm_validate_command(chip, buf, bufsiz)) return -EINVAL; if (bufsiz > TPM_BUFSIZE) diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 1ae9768..80fa606 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -127,7 +127,12 @@ enum tpm2_permanent_handles { }; enum tpm2_capabilities { - TPM2_CAP_TPM_PROPERTIES = 6, + TPM2_CAP_COMMANDS = 2, + TPM2_CAP_TPM_PROPERTIES = 6, +}; + +enum tpm2_properties { + TPM_PT_TOTAL_COMMANDS = 0x0129, }; enum tpm2_startup_types { @@ -135,6 +140,11 @@ enum tpm2_startup_types { TPM2_SU_STATE = 0x0001, }; +enum tpm2_cc_attrs { + TPM2_CC_ATTR_CHANDLES = 25, + TPM2_CC_ATTR_RHANDLE= 28, +}; + #define TPM_VID_INTEL0x8086 #define TPM_VID_WINBOND 0x1050 #define TPM_VID_STM 0x104A @@ -191,6 +201,9 @@ struct tpm_chip { acpi_handle acpi_dev_handle; char ppi_version[TPM_PPI_VERSION_LEN + 1]; #endif /* CONFIG_ACPI */ + + u32 nr_commands; + u32 *cc_attrs_tbl; }; #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) @@ -393,7 +406,8 @@ struct tpm_cmd_t { */ enum tpm_buf_flags { - TPM_BUF_OVERFLOW= BIT(0), + TPM_BUF_INITIALIZED = BIT(0), + TPM_BUF_OVERFLOW= BIT(1), }; struct tpm_buf { @@ -419,13 +433,17 @@ static inline int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal) head->length = cpu_to_be32(sizeof(*head)); head->ordinal = cpu_to_be32(ordinal); + buf->flags = TPM_BUF_INITIALIZED; + return 0; } static inline void tpm_buf_destroy(struct tpm_buf *buf) { - kunmap(buf->data_page); - __free_page(buf->data_page); + if (buf->flags & TPM_BUF_INITIALIZED) { + kunmap(buf->data_page); + __free_page(buf->data_page); + } } static inline u32 tpm_buf_length(struct tpm_buf *buf) @@ -545,4 +563,5 @@ int tpm2_auto_startup(struct tpm_chip *chip); void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type); unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); int tpm2_probe(struct tpm_chip *chip); +bool tpm2_find_cc_attrs(struct tpm_chip *chip, u32 cc, u32 *attrs); #endif diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 6eda239..c4d25b2 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -969,7 +969,10 @@ EXPORT_SYMBOL_GPL(tpm2_probe); */ int tpm2_auto_startup(struct tpm_chip *chip) { + struct tpm_buf buf; + u32 nr_commands; int rc; + int i; rc = tpm_get_timeouts(chip); if (rc) @@ -993,8 +996,56 @@ int tpm2_auto_startup(struct tpm_chip *chip) } } + rc = tpm2_get_tpm_pt(chip, TPM_PT_TOTAL_COMMANDS, &nr_commands, NULL); + if (rc) + goto out; + + chip->
Applied "regulator: core: Don't use regulators as supplies until the parent is bound" to the regulator tree
The patch regulator: core: Don't use regulators as supplies until the parent is bound has been applied to the regulator tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 66d228a2bf03b163ddaeca5f24f1ff89a84ad668 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 11 Jan 2017 17:44:25 + Subject: [PATCH] regulator: core: Don't use regulators as supplies until the parent is bound When regulators are successfully registered, we check to see if the regulator is a supply for any other registered regulator and if so add the new regulator as the supply for the existing regulator(s). Some devices, such as Power Management ICs, may register a series of regulators when probed and there are cases where one of the regulators may fail to register and defer the probing of the parent device. In this case any successfully registered regulators would be unregistered so that they can be re-registered at some time later when the probe is attempted again. However, if one of the regulators that was registered was added as a supply to another registered regulator (that did not belong to the same parent device), then this supply regulator was unregister again because the parent device is probe deferred, then a regulator could be holding an invalid reference to a supply regulator that has been unregistered. This will lead to a system crash if that regulator is then used. Although it would be possible to check when unregistering a regulator if any other regulator in the system is using it as a supply, it still may not be possible to remove it as a supply if this other regulator is in use. Therefore, fix this by preventing any regulator from adding another regulator as a supply if the parent device for the supply regulator has not been bound and if the parent device for the supply and the regulator are different. This will allow a parent device that is registering regulators to be probe deferred and ensure that none of the regulators it has registered are used as supplies for any other regulator from another device. Signed-off-by: Jon Hunter Signed-off-by: Mark Brown --- drivers/regulator/core.c | 13 + 1 file changed, 13 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 04baac9a165b..bcf67abd1cd2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1553,6 +1553,19 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) } } + /* +* If the supply's parent device is not the same as the +* regulator's parent device, then ensure the parent device +* is bound before we resolve the supply, in case the parent +* device get probe deferred and unregisters the supply. +*/ + if (r->dev.parent && r->dev.parent != rdev->dev.parent) { + if (!device_is_bound(r->dev.parent)) { + put_device(&r->dev); + return -EPROBE_DEFER; + } + } + /* Recursively resolve the supply of the supply */ ret = regulator_resolve_supply(r); if (ret < 0) { -- 2.11.0
Applied "regmap: Fixup the kernel-doc comments on functions/structures" to the regmap tree
The patch regmap: Fixup the kernel-doc comments on functions/structures has been applied to the regmap tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 2cf8e2dfdf88363476f23bc600745250b94dbbed Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 12 Jan 2017 11:17:39 + Subject: [PATCH] regmap: Fixup the kernel-doc comments on functions/structures Most of the kernel-doc comments in regmap don't actually generate correctly. This patch fixes up a few common issues, corrects some typos and adds some missing argument descriptions. The most common issues being using a : after the function name which causes the short description to not render correctly and not separating the long and short descriptions of the function. There are quite a few instances of arguments not being described or given the wrong name as well. This patch doesn't fixup functions/structures that are currently missing descriptions. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 20 +++ drivers/base/regmap/regmap-irq.c | 62 ++- drivers/base/regmap/regmap.c | 125 +-- include/linux/regmap.h | 115 --- 4 files changed, 179 insertions(+), 143 deletions(-) diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 4e582561e1e7..b0a0dcf32fb7 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -224,7 +224,7 @@ void regcache_exit(struct regmap *map) } /** - * regcache_read: Fetch the value of a given register from the cache. + * regcache_read - Fetch the value of a given register from the cache. * * @map: map to configure. * @reg: The register index. @@ -255,7 +255,7 @@ int regcache_read(struct regmap *map, } /** - * regcache_write: Set the value of a given register in the cache. + * regcache_write - Set the value of a given register in the cache. * * @map: map to configure. * @reg: The register index. @@ -328,7 +328,7 @@ static int regcache_default_sync(struct regmap *map, unsigned int min, } /** - * regcache_sync: Sync the register cache with the hardware. + * regcache_sync - Sync the register cache with the hardware. * * @map: map to configure. * @@ -396,7 +396,7 @@ int regcache_sync(struct regmap *map) EXPORT_SYMBOL_GPL(regcache_sync); /** - * regcache_sync_region: Sync part of the register cache with the hardware. + * regcache_sync_region - Sync part of the register cache with the hardware. * * @map: map to sync. * @min: first register to sync @@ -452,7 +452,7 @@ int regcache_sync_region(struct regmap *map, unsigned int min, EXPORT_SYMBOL_GPL(regcache_sync_region); /** - * regcache_drop_region: Discard part of the register cache + * regcache_drop_region - Discard part of the register cache * * @map: map to operate on * @min: first register to discard @@ -483,10 +483,10 @@ int regcache_drop_region(struct regmap *map, unsigned int min, EXPORT_SYMBOL_GPL(regcache_drop_region); /** - * regcache_cache_only: Put a register map into cache only mode + * regcache_cache_only - Put a register map into cache only mode * * @map: map to configure - * @cache_only: flag if changes should be written to the hardware + * @enable: flag if changes should be written to the hardware * * When a register map is marked as cache only writes to the register * map API will only update the register cache, they will not cause @@ -505,7 +505,7 @@ void regcache_cache_only(struct regmap *map, bool enable) EXPORT_SYMBOL_GPL(regcache_cache_only); /** - * regcache_mark_dirty: Indicate that HW registers were reset to default values + * regcache_mark_dirty - Indicate that HW registers were reset to default values * * @map: map to mark * @@ -527,10 +527,10 @@ void regcache_mark_dirty(struct regmap *map) EXPORT_SYMBOL_GPL(regcache_mark_dirty); /** - * regcache_cache_bypass: Put a register map into cache bypass mode + * regcache_cache_bypass - Put a register map into cache bypass mode * * @map: map to configure - * @cache_bypass: flag if changes should not be written to the cache + * @enabl
[PATCH RFC v2 2/5] tpm: export tpm2_flush_context_cmd
Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm.h | 2 ++ drivers/char/tpm/tpm2-cmd.c | 65 ++--- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 80fa606..c87c221 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -550,6 +550,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip) int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max); +void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, + unsigned int flags); int tpm2_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options); diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index c4d25b2..e2b4c75 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -401,6 +401,38 @@ static const struct tpm_input_header tpm2_get_tpm_pt_header = { }; /** + * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command + * @chip: TPM chip to use + * @payload: the key data in clear and encrypted form + * @options: authentication values and other options + * + * Return: same as with tpm_transmit_cmd + */ +void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, + unsigned int flags) +{ + struct tpm_buf buf; + int rc; + + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT); + if (rc) { + dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n", +handle); + return; + } + + tpm_buf_append_u32(&buf, handle); + + rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, +"flushing context"); + if (rc) + dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle, +rc); + + tpm_buf_destroy(&buf); +} + +/** * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer. * * @buf: an allocated tpm_buf instance @@ -603,39 +635,6 @@ static int tpm2_load_cmd(struct tpm_chip *chip, } /** - * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command - * - * @chip: TPM chip to use - * @handle: the key data in clear and encrypted form - * @flags: tpm transmit flags - * - * Return: Same as with tpm_transmit_cmd. - */ -static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle, - unsigned int flags) -{ - struct tpm_buf buf; - int rc; - - rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT); - if (rc) { - dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n", -handle); - return; - } - - tpm_buf_append_u32(&buf, handle); - - rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, - "flushing context"); - if (rc) - dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle, -rc); - - tpm_buf_destroy(&buf); -} - -/** * tpm2_unseal_cmd() - execute a TPM2_Unload command * * @chip: TPM chip to use -- 2.9.3
[PATCH RFC v2 0/5] RFC: in-kernel resource manager
This patch set adds support for TPM spaces that provide a context for isolating and swapping transient objects. This patch set does not yet include support for isolating policy and HMAC sessions but it is trivial to add once the basic approach is settled (and that's why I created an RFC patch set). v2: Changed to James' proposal of API. I did not make any other changes except split core TPM space code its own patch because I want to find consensus on the API before polishing the corners. Thus, this version also carries the RFC tag. I have not yet locked in my standpoint whether ioctl or a device file is a better deal. James Bottomley (2): tpm: split out tpm-dev.c into tpm-dev.c and tpm-common-dev.c tpm2: expose resource manager via a device link /dev/tpms Jarkko Sakkinen (3): tpm: validate TPM 2.0 commands tpm: export tpm2_flush_context_cmd tpm: infrastructure for TPM spaces drivers/char/tpm/Makefile | 2 +- drivers/char/tpm/tpm-chip.c | 61 +++- drivers/char/tpm/tpm-dev-common.c | 145 +++ drivers/char/tpm/tpm-dev.c| 141 ++ drivers/char/tpm/tpm-dev.h| 27 drivers/char/tpm/tpm-interface.c | 106 ++ drivers/char/tpm/tpm-sysfs.c | 2 +- drivers/char/tpm/tpm.h| 57 ++-- drivers/char/tpm/tpm2-cmd.c | 144 -- drivers/char/tpm/tpm2-space.c | 298 ++ drivers/char/tpm/tpms-dev.c | 57 11 files changed, 826 insertions(+), 214 deletions(-) create mode 100644 drivers/char/tpm/tpm-dev-common.c create mode 100644 drivers/char/tpm/tpm-dev.h create mode 100644 drivers/char/tpm/tpm2-space.c create mode 100644 drivers/char/tpm/tpms-dev.c -- 2.9.3
[PATCH RFC v2 3/5] tpm: infrastructure for TPM spaces
Added ability to tpm_transmit() to supply a TPM space that contains mapping from virtual handles to physical handles and backing storage for swapping transient objects. TPM space is isolated from other users of the TPM. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/Makefile| 2 +- drivers/char/tpm/tpm-chip.c | 7 + drivers/char/tpm/tpm-dev.c | 2 +- drivers/char/tpm/tpm-interface.c | 61 drivers/char/tpm/tpm-sysfs.c | 2 +- drivers/char/tpm/tpm.h | 22 ++- drivers/char/tpm/tpm2-cmd.c | 34 +++-- drivers/char/tpm/tpm2-space.c| 298 +++ 8 files changed, 382 insertions(+), 46 deletions(-) create mode 100644 drivers/char/tpm/tpm2-space.c diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index a05b1eb..251d0ed 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -3,7 +3,7 @@ # obj-$(CONFIG_TCG_TPM) += tpm.o tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ - tpm_eventlog.o +tpm_eventlog.o tpm2-space.o tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o tpm-$(CONFIG_OF) += tpm_of.o obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index c406343..993b9ae 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -128,6 +128,7 @@ static void tpm_dev_release(struct device *dev) mutex_unlock(&idr_lock); kfree(chip->log.bios_event_log); + kfree(chip->work_space.context_buf); kfree(chip); } @@ -189,6 +190,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, chip->cdev.owner = THIS_MODULE; chip->cdev.kobj.parent = &chip->dev.kobj; + chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!chip->work_space.context_buf) { + rc = -ENOMEM; + goto out; + } + return chip; out: diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index 912ad30..249eeb0 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -144,7 +144,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, mutex_unlock(&priv->buffer_mutex); return -EPIPE; } - out_size = tpm_transmit(priv->chip, priv->data_buffer, + out_size = tpm_transmit(priv->chip, NULL, priv->data_buffer, sizeof(priv->data_buffer), 0); tpm_put_ops(priv->chip); diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 0c5aba1..65fcd04c 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -370,10 +370,11 @@ static bool tpm_validate_command(struct tpm_chip *chip, const u8 *cmd, * 0 when the operation is successful. * A negative number for system errors (errno). */ -ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, -unsigned int flags) +ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, +u8 *buf, size_t bufsiz, unsigned int flags) { - ssize_t rc; + int rc; + ssize_t len = 0; u32 count, ordinal; unsigned long stop; @@ -399,10 +400,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, if (chip->dev.parent) pm_runtime_get_sync(chip->dev.parent); + rc = tpm2_prepare_space(chip, space, ordinal, buf, bufsiz); + if (rc) + goto out; + rc = chip->ops->send(chip, (u8 *) buf, count); if (rc < 0) { dev_err(&chip->dev, - "tpm_transmit: tpm_send: error %zd\n", rc); + "tpm_transmit: tpm_send: error %d\n", rc); goto out; } @@ -435,17 +440,23 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, goto out; out_recv: - rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); - if (rc < 0) + len = chip->ops->recv(chip, (u8 *) buf, bufsiz); + if (len < 0) { dev_err(&chip->dev, - "tpm_transmit: tpm_recv: error %zd\n", rc); + "tpm_transmit: tpm_recv: error %d\n", rc); + rc = len; + goto out; + } + + rc = tpm2_commit_space(chip, space, ordinal, buf, bufsiz); + out: if (chip->dev.parent) pm_runtime_put_sync(chip->dev.parent); if (!(flags & TPM_TRANSMIT_UNLOCKED)) mutex_unlock(&chip->tpm_mutex); - return rc; + return rc ? rc : len; } /** @@ -463,13 +474,14 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, * A negative number for system errors (errno). * A positive number for a TPM error. */ -ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd
[PATCH] xen-netback: fix memory leaks on XenBus disconnect
Eliminate memory leaks introduced several years ago by cleaning the queue resources which are allocated on XenBus connection event. Namely, queue structure array and pages used for IO rings. vif->lock is used to protect statistics gathering agents from using the queue structure during cleaning. Signed-off-by: Igor Druzhinin --- drivers/net/xen-netback/interface.c | 6 -- drivers/net/xen-netback/xenbus.c| 13 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index e30ffd2..5795213 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev) { struct xenvif *vif = netdev_priv(dev); struct xenvif_queue *queue = NULL; - unsigned int num_queues = vif->num_queues; unsigned long rx_bytes = 0; unsigned long rx_packets = 0; unsigned long tx_bytes = 0; unsigned long tx_packets = 0; unsigned int index; + spin_lock(&vif->lock); if (vif->queues == NULL) goto out; /* Aggregate tx and rx stats from each queue */ - for (index = 0; index < num_queues; ++index) { + for (index = 0; index < vif->num_queues; ++index) { queue = &vif->queues[index]; rx_bytes += queue->stats.rx_bytes; rx_packets += queue->stats.rx_packets; @@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct net_device *dev) } out: + spin_unlock(&vif->lock); + vif->dev->stats.rx_bytes = rx_bytes; vif->dev->stats.rx_packets = rx_packets; vif->dev->stats.tx_bytes = tx_bytes; diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 3124eae..85b742e 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -493,11 +493,22 @@ static int backend_create_xenvif(struct backend_info *be) static void backend_disconnect(struct backend_info *be) { if (be->vif) { + unsigned int queue_index; + xen_unregister_watchers(be->vif); #ifdef CONFIG_DEBUG_FS xenvif_debugfs_delif(be->vif); #endif /* CONFIG_DEBUG_FS */ xenvif_disconnect_data(be->vif); + for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index) + xenvif_deinit_queue(&be->vif->queues[queue_index]); + + spin_lock(&be->vif->lock); + vfree(be->vif->queues); + be->vif->num_queues = 0; + be->vif->queues = NULL; + spin_unlock(&be->vif->lock); + xenvif_disconnect_ctrl(be->vif); } } @@ -1034,6 +1045,8 @@ static void connect(struct backend_info *be) err: if (be->vif->num_queues > 0) xenvif_disconnect_data(be->vif); /* Clean up existing queues */ + for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index) + xenvif_deinit_queue(&be->vif->queues[queue_index]); vfree(be->vif->queues); be->vif->queues = NULL; be->vif->num_queues = 0; -- 1.8.3.1
Re: [PATCH v7 7/7] perf/amd/iommu: Enable support for multiple IOMMUs
On Mon, Jan 09, 2017 at 09:33:47PM -0600, Suravee Suthikulpanit wrote: > This patch adds multi-IOMMU support for perf by exposing > an AMD IOMMU PMU for each IOMMU found in the system via: > > /sys/device/amd_iommu_x /* where x is the IOMMU index. */ Straight into the top-level devices hierarchy? Why not add a proper hierarchy to /sys/devices/system/iommu/ ... ? Jörg, don't you have a sane iommu hierarchy already in sysfs? > This allows users to specify different events to be programed > onto performance counters of each IOMMU. > > Cc: Peter Zijlstra > Cc: Borislav Petkov > Signed-off-by: Suravee Suthikulpanit > --- > arch/x86/events/amd/iommu.c | 119 > > 1 file changed, 64 insertions(+), 55 deletions(-) > > diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c > index 2403c78..5fd97b5 100644 > --- a/arch/x86/events/amd/iommu.c > +++ b/arch/x86/events/amd/iommu.c > @@ -35,10 +35,13 @@ > #define _GET_PASID_MASK(ev) ((ev->hw.extra_reg.config >> 16) & 0xULL) > #define _GET_DOMID_MASK(ev) ((ev->hw.extra_reg.config >> 32) & 0xULL) > > -static struct perf_amd_iommu __perf_iommu; > +#define PERF_AMD_IOMMU_NAME_SZ 16 > > struct perf_amd_iommu { > + struct list_head list; > struct pmu pmu; > + uint idx; This uint thing has crept in: $ git grep "uint " arch/x86/ arch/x86/crypto/crc32-pclmul_asm.S:101: * uint crc32_pclmul_le_16(unsigned char const *buffer, arch/x86/crypto/crc32-pclmul_asm.S:102: *size_t len, uint crc32) arch/x86/events/amd/iommu.h:32:extern u8 amd_iommu_pc_get_max_banks(uint idx); arch/x86/events/amd/iommu.h:34:extern u8 amd_iommu_pc_get_max_counters(uint idx); arch/x86/events/amd/iommu.h:36:extern int amd_iommu_pc_set_reg(uint idx, u16 devid, u8 bank, u8 cntr, arch/x86/events/amd/iommu.h:39:extern int amd_iommu_pc_set_counter(uint idx, u8 bank, u8 cntr, u64 *value); arch/x86/events/amd/iommu.h:41:extern int amd_iommu_pc_get_counter(uint idx, u8 bank, u8 cntr, u64 *value); "unsigned int" please. > + char name[PERF_AMD_IOMMU_NAME_SZ]; > u8 max_banks; > u8 max_counters; > u64 cntr_assign_mask; > @@ -46,6 +49,8 @@ struct perf_amd_iommu { > const struct attribute_group *attr_groups[4]; > }; > > +LIST_HEAD(perf_amd_iommu_list); static > + > #define format_group attr_groups[0] > #define cpumask_groupattr_groups[1] > #define events_group attr_groups[2] > @@ -204,8 +209,7 @@ static int clear_avail_iommu_bnk_cntr(struct > perf_amd_iommu *perf_iommu, > static int perf_iommu_event_init(struct perf_event *event) > { > struct hw_perf_event *hwc = &event->hw; > - struct perf_amd_iommu *perf_iommu; > - u64 config, config1; > + struct perf_amd_iommu *pi = container_of(event->pmu, struct > perf_amd_iommu, pmu); Do this deref when you actually need it: struct perf_amd_iommu *pi; because you might exit earlier and end up doing it for nothing. > > /* test the event attr type check for PMU enumeration */ > if (event->attr.type != event->pmu->type) > @@ -227,27 +231,17 @@ static int perf_iommu_event_init(struct perf_event > *event) > if (event->cpu < 0) > return -EINVAL; > > - perf_iommu = &__perf_iommu; > - > - if (event->pmu != &perf_iommu->pmu) > - return -ENOENT; > - > - if (perf_iommu) { > - config = event->attr.config; > - config1 = event->attr.config1; > - } else { > - return -EINVAL; > - } > - > /* update the hw_perf_event struct with the iommu config data */ > - hwc->config = config; > - hwc->extra_reg.config = config1; ---> here: pi = container_of(event->pmu, struct perf_amd_iommu, pmu); > + hwc->idx = pi->idx; > + hwc->config = event->attr.config; > + hwc->extra_reg.config = event->attr.config1; Align vertically on the = sign. > > return 0; > } > > static void perf_iommu_enable_event(struct perf_event *ev) > { > + struct hw_perf_event *hwc = &ev->hw; > u8 csource = _GET_CSOURCE(ev); > u16 devid = _GET_DEVID(ev); > u8 bank = _GET_BANK(ev); ... > static void perf_iommu_disable_event(struct perf_event *event) > { > + struct hw_perf_event *hwc = &event->hw; > u64 reg = 0ULL; > > - amd_iommu_pc_set_reg(0, _GET_DEVID(event), _GET_BANK(event), > + amd_iommu_pc_set_reg(hwc->idx, _GET_DEVID(event), _GET_BANK(event), >_GET_CNTR(event), IOMMU_PC_COUNTER_SRC_REG, ®); > } > > @@ -301,7 +296,7 @@ static void perf_iommu_start(struct perf_event *event, > int flags) > > val = local64_read(&hwc->prev_count); > > - amd_iommu_pc_set_counter(0, _GET_BANK(event), _GET_CNTR(event), &val); > + amd_iommu_pc_set_counter(hwc->idx, _GET_BANK(event), _GET_CNTR(event), > &val); > enable: > perf_iommu_enable_event(event); > perf_event_update_userpage(
Re: [PATCH/RESEND v2 3/5] z3fold: extend compaction function
On Wed, Jan 11, 2017 at 3:52 PM, Vitaly Wool wrote: > On Wed, 11 Jan 2017 17:43:13 +0100 > Vitaly Wool wrote: > >> On Wed, Jan 11, 2017 at 5:28 PM, Dan Streetman wrote: >> > On Wed, Jan 11, 2017 at 10:06 AM, Vitaly Wool wrote: >> >> z3fold_compact_page() currently only handles the situation when >> >> there's a single middle chunk within the z3fold page. However it >> >> may be worth it to move middle chunk closer to either first or >> >> last chunk, whichever is there, if the gap between them is big >> >> enough. >> >> >> >> This patch adds the relevant code, using BIG_CHUNK_GAP define as >> >> a threshold for middle chunk to be worth moving. >> >> >> >> Signed-off-by: Vitaly Wool >> >> --- >> >> mm/z3fold.c | 26 +- >> >> 1 file changed, 25 insertions(+), 1 deletion(-) >> >> >> >> diff --git a/mm/z3fold.c b/mm/z3fold.c >> >> index 98ab01f..fca3310 100644 >> >> --- a/mm/z3fold.c >> >> +++ b/mm/z3fold.c >> >> @@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct >> >> z3fold_header *zhdr, >> >>zhdr->middle_chunks << CHUNK_SHIFT); >> >> } >> >> >> >> +#define BIG_CHUNK_GAP 3 >> >> /* Has to be called with lock held */ >> >> static int z3fold_compact_page(struct z3fold_header *zhdr) >> >> { >> >> @@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header >> >> *zhdr) >> >> zhdr->middle_chunks = 0; >> >> zhdr->start_middle = 0; >> >> zhdr->first_num++; >> >> + return 1; >> >> } >> >> - return 1; >> >> + >> >> + /* >> >> +* moving data is expensive, so let's only do that if >> >> +* there's substantial gain (at least BIG_CHUNK_GAP chunks) >> >> +*/ >> >> + if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 && >> >> + zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >= >> >> + BIG_CHUNK_GAP) { >> >> + mchunk_memmove(zhdr, zhdr->first_chunks + 1); >> >> + zhdr->start_middle = zhdr->first_chunks + 1; >> > >> > this should be first_chunks + ZHDR_CHUNKS, not + 1. >> > >> >> + return 1; >> >> + } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 && >> >> + TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle >> >> + + zhdr->middle_chunks) >= >> >> + BIG_CHUNK_GAP) { >> >> + unsigned short new_start = NCHUNKS - zhdr->last_chunks - >> > >> > this should be TOTAL_CHUNKS, not NCHUNKS. >> >> Right :/ > > So here we go: > > > z3fold_compact_page() currently only handles the situation when > there's a single middle chunk within the z3fold page. However it > may be worth it to move middle chunk closer to either first or > last chunk, whichever is there, if the gap between them is big > enough. > > This patch adds the relevant code, using BIG_CHUNK_GAP define as > a threshold for middle chunk to be worth moving. > > Signed-off-by: Vitaly Wool Acked-by: Dan Streetman > --- > mm/z3fold.c | 26 +- > 1 file changed, 25 insertions(+), 1 deletion(-) > > diff --git a/mm/z3fold.c b/mm/z3fold.c > index 98ab01f..fca3310 100644 > --- a/mm/z3fold.c > +++ b/mm/z3fold.c > @@ -268,6 +268,7 @@ static inline void *mchunk_memmove(struct z3fold_header > *zhdr, >zhdr->middle_chunks << CHUNK_SHIFT); > } > > +#define BIG_CHUNK_GAP 3 > /* Has to be called with lock held */ > static int z3fold_compact_page(struct z3fold_header *zhdr) > { > @@ -286,8 +287,31 @@ static int z3fold_compact_page(struct z3fold_header > *zhdr) > zhdr->middle_chunks = 0; > zhdr->start_middle = 0; > zhdr->first_num++; > + return 1; > } > - return 1; > + > + /* > +* moving data is expensive, so let's only do that if > +* there's substantial gain (at least BIG_CHUNK_GAP chunks) > +*/ > + if (zhdr->first_chunks != 0 && zhdr->last_chunks == 0 && > + zhdr->start_middle - (zhdr->first_chunks + ZHDR_CHUNKS) >= > + BIG_CHUNK_GAP) { > + mchunk_memmove(zhdr, zhdr->first_chunks + ZHDR_CHUNKS); > + zhdr->start_middle = zhdr->first_chunks + ZHDR_CHUNKS; > + return 1; > + } else if (zhdr->last_chunks != 0 && zhdr->first_chunks == 0 && > + TOTAL_CHUNKS - (zhdr->last_chunks + zhdr->start_middle > + + zhdr->middle_chunks) >= > + BIG_CHUNK_GAP) { > + unsigned short new_start = TOTAL_CHUNKS - zhdr->last_chunks - > + zhdr->middle_chunks; > + mchunk_memmove(zhdr, new_start); > + zhdr->start_middle = new_start; > + return 1; > + } > + > + return 0; > } > > /** > -- > 2.4.2
Re: [PATCH v4 0/4] Application Data Integrity feature introduced by SPARC M7
On 01/12/2017 08:50 AM, Khalid Aziz wrote: > 2. Any shared page that has ADI protection enabled on it, must stay ADI > protected across all processes sharing it. Is that true? What happens if a page with ADI tags set is accessed via a PTE without the ADI enablement bit set? > COW creates an intersection of the two. It creates a new copy of the > shared data. It is a new data page and hence the process creating it > must be the one responsible for enabling ADI protection on it. Do you mean that the application must be responsible? Or the kernel running in the context of the new process must be responsible? > It is also a copy of what was ADI protected data, so should it > inherit the protection instead? I think the COW'd copy must inherit the VMA bit, the PTE bits, and the tags on the cachelines. > I misspoke earlier. I had misinterpreted the results of test I ran. > Changing the tag on shared memory is allowed by memory controller. The > requirement is every one sharing the page must switch to the new tag or > else they get SIGSEGV. I asked this in the last mail, but I guess I'll ask it again. Please answer this directly. If we require that everyone coordinate their tags on the backing physical memory, and we allow a lower-privileged program to access the same data as a more-privileged one, then the lower-privilege app can cause arbitrary crashes in the privileged application. For instance, say sudo mmap()'s /etc/passwd and uses ADI tags to protect the mapping. Couldn't any other app in the system prevent sudo from working? How can we *EVER* allow tags to be set on non-writable mappings? > I am inclined to suggest we copy the tags to the new data page on COW > and that will continue to enforce ADI on the COW'd pages even though > COW'd pages are new data pages. This is the logically consistent > behavior. Does that make sense? Yes, I think this is what you have to do.
Re: [PATCH/RESEND v2 5/5] z3fold: add kref refcounting
On Wed, Jan 11, 2017 at 3:51 PM, Vitaly Wool wrote: > On Wed, 11 Jan 2017 13:03:06 -0500 > Dan Streetman wrote: > > >> >>> provided that I take the lock for the headless case above. That will >> >>> work won't it? >> >> >> >> in this specific case - since every single kref_put in the driver is >> >> protected by the pool lock - yeah, you can do that, since you know >> >> that specific kref_put didn't free the page and no other kref_put >> >> could happen since you're holding the pool lock. >> >> >> >> but that specific requirement isn't made obvious by the code, and I >> >> can see how a future patch could release the pool lock between the >> >> kref_put and lru list add, without realizing that introduces a bug. >> >> isn't it better to just add it to the lru list before you put the >> >> kref? just a suggestion. >> > >> > That would require to add it to the lru separately for headless pages >> > above, I don't think it makes things better or less error prone. >> > I would rather add a comment before list_add. >> > >> >> i'd also suggest the pages_nr dec go into the page release function, >> >> instead of checking every kref_put return value; that's easier and >> >> less prone to forgetting to check one of the kref_puts. >> > >> > That will mean z3fold_header should contain a pointer to its pool. I'm >> > not sure it is worth it but I can do that :) >> >> the header's already rounded up to chunk size, so if there's room then >> it won't take any extra memory. but it works either way. > > So let's have it like this then: > > > With both coming and already present locking optimizations, > introducing kref to reference-count z3fold objects is the right > thing to do. Moreover, it makes buddied list no longer necessary, > and allows for a simpler handling of headless pages. > > Signed-off-by: Vitaly Wool Reviewed-by: Dan Streetman > --- > mm/z3fold.c | 151 > ++-- > 1 file changed, 66 insertions(+), 85 deletions(-) > > diff --git a/mm/z3fold.c b/mm/z3fold.c > index 4325bde..f0d2eaf 100644 > --- a/mm/z3fold.c > +++ b/mm/z3fold.c > @@ -52,6 +52,7 @@ enum buddy { > * z3fold page, except for HEADLESS pages > * @buddy: links the z3fold page into the relevant list in the pool > * @page_lock: per-page lock > + * @refcount: reference cound for the z3fold page > * @first_chunks: the size of the first buddy in chunks, 0 if free > * @middle_chunks: the size of the middle buddy in chunks, 0 if free > * @last_chunks: the size of the last buddy in chunks, 0 if free > @@ -60,6 +61,7 @@ enum buddy { > struct z3fold_header { > struct list_head buddy; > spinlock_t page_lock; > + struct kref refcount; > unsigned short first_chunks; > unsigned short middle_chunks; > unsigned short last_chunks; > @@ -95,8 +97,6 @@ struct z3fold_header { > * @unbuddied: array of lists tracking z3fold pages that contain 2- buddies; > * the lists each z3fold page is added to depends on the size of > * its free region. > - * @buddied: list tracking the z3fold pages that contain 3 buddies; > - * these z3fold pages are full > * @lru: list tracking the z3fold pages in LRU order by most recently > * added buddy. > * @pages_nr: number of z3fold pages in the pool. > @@ -109,7 +109,6 @@ struct z3fold_header { > struct z3fold_pool { > spinlock_t lock; > struct list_head unbuddied[NCHUNKS]; > - struct list_head buddied; > struct list_head lru; > atomic64_t pages_nr; > const struct z3fold_ops *ops; > @@ -121,8 +120,7 @@ struct z3fold_pool { > * Internal z3fold page flags > */ > enum z3fold_page_flags { > - UNDER_RECLAIM = 0, > - PAGE_HEADLESS, > + PAGE_HEADLESS = 0, > MIDDLE_CHUNK_MAPPED, > }; > > @@ -146,11 +144,11 @@ static struct z3fold_header *init_z3fold_page(struct > page *page) > struct z3fold_header *zhdr = page_address(page); > > INIT_LIST_HEAD(&page->lru); > - clear_bit(UNDER_RECLAIM, &page->private); > clear_bit(PAGE_HEADLESS, &page->private); > clear_bit(MIDDLE_CHUNK_MAPPED, &page->private); > > spin_lock_init(&zhdr->page_lock); > + kref_init(&zhdr->refcount); > zhdr->first_chunks = 0; > zhdr->middle_chunks = 0; > zhdr->last_chunks = 0; > @@ -161,9 +159,21 @@ static struct z3fold_header *init_z3fold_page(struct > page *page) > } > > /* Resets the struct page fields and frees the page */ > -static void free_z3fold_page(struct z3fold_header *zhdr) > +static void free_z3fold_page(struct page *page) > { > - __free_page(virt_to_page(zhdr)); > + __free_page(page); > +} > + > +static void release_z3fold_page(struct kref *ref) > +{ > + struct z3fold_header *zhdr = container_of(ref, struct z3fold_header, > +
Re: [PATCH] power: reset: Add MAX77620 support
On Thursday 12 January 2017 11:05 PM, Thierry Reding wrote: * PGP Signed by an unknown key On Thu, Jan 12, 2017 at 10:06:24PM +0530, Laxman Dewangan wrote: On Thursday 12 January 2017 09:45 PM, Thierry Reding wrote: + dev_dbg(&pdev->dev, "event recorder: %#x\n", value); + + system_power_controller = power; + pm_power_off = max77620_pm_power_off; +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) + arm_pm_restart = max77620_pm_restart; What if we want to reset via the Tegra and not through PMIC? In that case I assume we either don't have a PMIC, or we should not add the system-power-controller device tree property to the PMIC node. In the latter case this driver won't install any power off or restart callbacks. We need reset from Tegra and power of from PMIC. Tegra does not support power OFF.
Re: [PATCH v8 2/5] i2c: Add STM32F4 I2C driver
On Thu, Jan 12, 2017 at 02:47:42PM +0100, M'boumba Cedric Madianga wrote: > 2017-01-12 13:03 GMT+01:00 Uwe Kleine-König : > > Hello Cedric, > > > > On Thu, Jan 12, 2017 at 12:23:12PM +0100, M'boumba Cedric Madianga wrote: > >> 2017-01-11 16:39 GMT+01:00 Uwe Kleine-König > >> : > >> > On Wed, Jan 11, 2017 at 02:58:44PM +0100, M'boumba Cedric Madianga wrote: > >> >> 2017-01-11 9:22 GMT+01:00 Uwe Kleine-König > >> >> : > >> >> > This is surprising. I didn't recheck the manual, but that looks very > >> >> > uncomfortable. > >> >> > >> >> I agree but this exactly the hardware way of working described in the > >> >> reference manual. > >> > > >> > IMHO that's a hw bug. This makes it for example impossible to implement > >> > SMBus block transfers (I think). > >> > >> This is not correct. > >> Setting STOP/START bit does not mean the the pulse will be sent right now. > >> Here we have just to prepare the hardware for the 2 next pulse but the > >> STOP/START/ACK pulse will be generated at the right time as required > >> by I2C specification. > >> So SMBus block transfer will be possible. > > > > A block transfer consists of a byte that specifies the count of bytes > > yet to come. So the device sends for example: > > > > 0x01 0xab > > > > So when you read the 1 in the first byte it's already too late to set > > STOP to get it after the 2nd byte. > > > > Not sure I got all the required details right, though. > > Ok I understand your use case but I always think that the harware manages it. > If I take the above example, the I2C SMBus block read transaction will > be as below: > S Addr Wr [A] Comm [A] >S Addr Rd [A] [Count] A [Data1] A [Data2] NA P > > The first message is a single byte-transmission so there is no problem. > > The second message is a N-byte reception with N = 3 > > When the I2C controller has finished to send the device address (S > Addr Rd), the ADDR flag is set and an interrupt is raised. > In the routine that handles ADDR event, we set ACK bit in order to > generate ACK pulse as soon as a data byte is received in the shift > register and then we clear the ADDR flag. > Please note that the SCL line is stretched low until ADDR flag is cleared. > So, as far I understand, the device could not sent any data as long as > the SCL line is stretched low. Right ? > > Then, as soon as the SCL line is high, the device could send the first > data byte (Count). > When this byte is received in the shift register, an ACK is > automatically generated as defined during adress match phase and the > data byte is pushed in DR (data register). > Then, an interrupt is raised as RXNE (RX not empty) flag is set. > In the routine that handles RXNE event, as N=3, we just clear all > buffer interrupts in order to avoid another system preemption due to > RXNE event but we does not read the data in DR. In my example I want to receive a block of length 1, so only two bytes are read, a 1 (the length) and the data byte (0xab in my example). I think that as soon as you read the 1 it's already to late to schedule the NA after the next byte? Best regards Uwe -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH 1/2] memory: aemif: allow passing device lookup table as platform data
On 1/4/17 2:36 AM, Bartosz Golaszewski wrote: TI aemif driver creates its own subnodes of the device tree in order to guarantee that all child devices are probed after the AEMIF timing parameters are configured. Some devices (e.g. da850) use struct of_dev_auxdata for clock lookup but nodes created from within the aemif driver can't access the lookup table. Create a platform data structure that holds a pointer to of_dev_auxdata so that we can use it with of_platform_populate(). Signed-off-by: Bartosz Golaszewski --- Patch looks fine to me. Did I miss PATCH 2/2 ? drivers/memory/* patches has been queue via Greg KH tree. Please repost your series with acks and copy Greg. I will request Greg to queue these changes via his tree. Regards, Santosh
Re: [PATCH V2 1/4] PCI: exynos: replace to one register accessor from each accessors
On Thu, Jan 12, 2017 at 11:17:16AM +0900, Jaehoon Chung wrote: > There is no reason to maintain *_blk/phy/elbi_* as register accessors. > It can be replaced to one register accessor. > > Signed-off-by: Jaehoon Chung > Reviewed-by: Pankaj Dubey > Acked-by: Krzysztof Kozlowski > --- > Changelog on V2; > - Changes the all pointer names as "ep" instead of "exynos_pcie" Thanks a lot for making this consistency change. I should have mentioned this in the first response, but I would prefer to see this as two separate patches: 1) Rename all pointer names from "exynos_pcie" to "ep" 2) Replace the *_blk/*_phy/*_elb accessors That makes the patches smaller and easier to review, since each does only one thing. > drivers/pci/host/pci-exynos.c | 354 > -- > 1 file changed, 167 insertions(+), 187 deletions(-) > > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c > index f1c544b..92856cd 100644 > --- a/drivers/pci/host/pci-exynos.c > +++ b/drivers/pci/host/pci-exynos.c > @@ -102,212 +102,190 @@ struct exynos_pcie { > #define PCIE_PHY_TRSV3_PD_TSV(0x1 << 7) > #define PCIE_PHY_TRSV3_LVCC 0x31c > > -static void exynos_elb_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 > reg) > +static void exynos_pcie_writel(void __iomem *base, u32 val, u32 reg) > { > - writel(val, exynos_pcie->elbi_base + reg); > + writel(val, base + reg); > } > > -static u32 exynos_elb_readl(struct exynos_pcie *exynos_pcie, u32 reg) > +static u32 exynos_pcie_readl(void __iomem *base, u32 reg) > { > - return readl(exynos_pcie->elbi_base + reg); > + return readl(base + reg); > } > > -static void exynos_phy_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 > reg) > -{ > - writel(val, exynos_pcie->phy_base + reg); > -} > - > -static u32 exynos_phy_readl(struct exynos_pcie *exynos_pcie, u32 reg) > -{ > - return readl(exynos_pcie->phy_base + reg); > -} > - > -static void exynos_blk_writel(struct exynos_pcie *exynos_pcie, u32 val, u32 > reg) > -{ > - writel(val, exynos_pcie->block_base + reg); > -} > - > -static u32 exynos_blk_readl(struct exynos_pcie *exynos_pcie, u32 reg) > -{ > - return readl(exynos_pcie->block_base + reg); > -} > - > -static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *exynos_pcie, > - bool on) > +static void exynos_pcie_sideband_dbi_w_mode(struct exynos_pcie *ep, bool on) > { > u32 val; > > if (on) { > - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC); > + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC); > val |= PCIE_ELBI_SLV_DBI_ENABLE; > - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC); > + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC); > } else { > - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC); > + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_AWMISC); > val &= ~PCIE_ELBI_SLV_DBI_ENABLE; > - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC); > + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_AWMISC); > } > } > > -static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *exynos_pcie, > - bool on) > +static void exynos_pcie_sideband_dbi_r_mode(struct exynos_pcie *ep, bool on) > { > u32 val; > > if (on) { > - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC); > + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC); > val |= PCIE_ELBI_SLV_DBI_ENABLE; > - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_ARMISC); > + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC); > } else { > - val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC); > + val = exynos_pcie_readl(ep->elbi_base, PCIE_ELBI_SLV_ARMISC); > val &= ~PCIE_ELBI_SLV_DBI_ENABLE; > - exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_ARMISC); > + exynos_pcie_writel(ep->elbi_base, val, PCIE_ELBI_SLV_ARMISC); > } > } > > -static void exynos_pcie_assert_core_reset(struct exynos_pcie *exynos_pcie) > +static void exynos_pcie_assert_core_reset(struct exynos_pcie *ep) > { > u32 val; > > - val = exynos_elb_readl(exynos_pcie, PCIE_CORE_RESET); > + val = exynos_pcie_readl(ep->elbi_base, PCIE_CORE_RESET); > val &= ~PCIE_CORE_RESET_ENABLE; > - exynos_elb_writel(exynos_pcie, val, PCIE_CORE_RESET); > - exynos_elb_writel(exynos_pcie, 0, PCIE_PWR_RESET); > - exynos_elb_writel(exynos_pcie, 0, PCIE_STICKY_RESET); > - exynos_elb_writel(exynos_pcie, 0, PCIE_NONSTICKY_RESET); > + exynos_pcie_writel(ep->elbi_base, val, PCIE_CORE_RESET); > + exynos_pcie_writel(ep->elbi_base, 0, PCIE_PWR_RESET)
Re: [PATCH v5] DAX: enable iostat for read/write
On Thu, 2017-01-12 at 11:38 -0700, Toshi Kani wrote: > DAX IO path does not support iostat, but its metadata IO path does. > Therefore, iostat shows metadata IO statistics only, which has been > confusing to users. [] > diff --git a/fs/dax.c b/fs/dax.c [] > @@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter > *iter, > { > struct address_space *mapping = iocb->ki_filp->f_mapping; > struct inode *inode = mapping->host; > + struct gendisk *disk = inode->i_sb->s_bdev->bd_disk; > loff_t pos = iocb->ki_pos, ret = 0, done = 0; > unsigned flags = 0; > + unsigned long start = 0; > + int do_acct = blk_queue_io_stat(disk->queue); > > if (iov_iter_rw(iter) == WRITE) > flags |= IOMAP_WRITE; > > + if (do_acct) { > + sector_t sec = iov_iter_count(iter) >> 9; > + > + start = jiffies; > + generic_start_io_acct(iov_iter_rw(iter), > + min_t(unsigned long, 1, sec), I believe I mislead you with a thinko. Your original code was (!sec) ? 1 : sec and I suggested incorrectly using min_t It should of course be max_t. Sorry. Also, as sec is now sector_t (u64), perhaps this unsigned long cast is incorrect.
[PATCH] ASoC: rt5659: fix platform_no_drv_owner.cocci warnings
sound/soc/codecs/rt5659.c:4236:3-8: No need to set .owner here. The core will do it. Remove .owner field if calls are used which set it automatically Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci CC: Nicholas Mc Guire Signed-off-by: Fengguang Wu --- rt5659.c |1 - 1 file changed, 1 deletion(-) --- a/sound/soc/codecs/rt5659.c +++ b/sound/soc/codecs/rt5659.c @@ -4233,7 +4233,6 @@ MODULE_DEVICE_TABLE(acpi, rt5659_acpi_ma static struct i2c_driver rt5659_i2c_driver = { .driver = { .name = "rt5659", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(rt5659_of_match), .acpi_match_table = ACPI_PTR(rt5659_acpi_match), },
[PATCH v5 3/3] Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup
The Marvell devices may have many gpio pins, and hence for wakeup on these out-of-band pins, the chip needs to be told which pin is to be used for wakeup, using an hci command. Thus, we read the pin number etc from the device tree node and send a command to the chip. Signed-off-by: Rajat Jain Reviewed-by: Brian Norris Acked-by: Rob Herring --- v5: same as v5 v4: same as v3 v3: * remove the Marvell specific id table and check * Add reference to marvell-bt-8xxx.txt in btusb.txt * Add "Reviewed-by" and "Acked-by" v2: Fix the binding document to specify to use "wakeup" interrupt-name Documentation/devicetree/bindings/net/btusb.txt| 3 ++ .../{marvell-bt-sd8xxx.txt => marvell-bt-8xxx.txt} | 46 +++ drivers/bluetooth/btusb.c | 51 ++ 3 files changed, 92 insertions(+), 8 deletions(-) rename Documentation/devicetree/bindings/net/{marvell-bt-sd8xxx.txt => marvell-bt-8xxx.txt} (50%) diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt index 2c0355c85972..01fa2d4188d4 100644 --- a/Documentation/devicetree/bindings/net/btusb.txt +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -10,6 +10,9 @@ Required properties: "usb1286,204e" (Marvell 8997) +Also, vendors that use btusb may have device additional properties, e.g: +Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt + Optional properties: - interrupt-parent: phandle of the parent interrupt controller diff --git a/Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt similarity index 50% rename from Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt rename to Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt index 6a9a63cb0543..9be1059ff03f 100644 --- a/Documentation/devicetree/bindings/net/marvell-bt-sd8xxx.txt +++ b/Documentation/devicetree/bindings/net/marvell-bt-8xxx.txt @@ -1,16 +1,21 @@ -Marvell 8897/8997 (sd8897/sd8997) bluetooth SDIO devices +Marvell 8897/8997 (sd8897/sd8997) bluetooth devices (SDIO or USB based) -- +The 8997 devices supports multiple interfaces. When used on SDIO interfaces, +the btmrvl driver is used and when used on USB interface, the btusb driver is +used. Required properties: - compatible : should be one of the following: - * "marvell,sd8897-bt" - * "marvell,sd8997-bt" + * "marvell,sd8897-bt" (for SDIO) + * "marvell,sd8997-bt" (for SDIO) + * "usb1286,204e" (for USB) Optional properties: - marvell,cal-data: Calibration data downloaded to the device during initialization. This is an array of 28 values(u8). + This is only applicable to SDIO devices. - marvell,wakeup-pin: It represents wakeup pin number of the bluetooth chip. firmware will use the pin to wakeup host system (u16). @@ -18,10 +23,15 @@ Optional properties: platform. The value will be configured to firmware. This is needed to work chip's sleep feature as expected (u16). - interrupt-parent: phandle of the parent interrupt controller - - interrupts : interrupt pin number to the cpu. Driver will request an irq based -on this interrupt number. During system suspend, the irq will be -enabled so that the bluetooth chip can wakeup host platform under -certain condition. During system resume, the irq will be disabled + - interrupt-names: Used only for USB based devices (See below) + - interrupts : specifies the interrupt pin number to the cpu. For SDIO, the +driver will use the first interrupt specified in the interrupt +array. For USB based devices, the driver will use the interrupt +named "wakeup" from the interrupt-names and interrupt arrays. +The driver will request an irq based on this interrupt number. +During system suspend, the irq will be enabled so that the +bluetooth chip can wakeup host platform under certain +conditions. During system resume, the irq will be disabled to make sure unnecessary interrupt is not received. Example: @@ -29,7 +39,9 @@ Example: IRQ pin 119 is used as system wakeup source interrupt. wakeup pin 13 and gap 100ms are configured so that firmware can wakeup host using this device side pin and wakeup latency. -calibration data is also available in below example. + +Example for SDIO device follows (calibration data is also available in +below example). &mmc3 { status = "okay"; @@ -54,3 +66,21 @@ calibration data is also available in below example. marvell,wakeup-gap-ms = /bits/ 16 <0x64>; }; }; + +Example for USB device: + +&usb_host1_ohci { +status = "okay"; +#address-cells = <1>; +#si
[PATCH v5 2/3] Bluetooth: btusb: Add out-of-band wakeup support
Some onboard BT chips (e.g. Marvell 8997) contain a wakeup pin that can be connected to a gpio on the CPU side, and can be used to wakeup the host out-of-band. This can be useful in situations where the in-band wakeup is not possible or not preferable (e.g. the in-band wakeup may require the USB host controller to remain active, and hence consuming more system power during system sleep). The oob gpio interrupt to be used for wakeup on the CPU side, is read from the device tree node, (using standard interrupt descriptors). A devcie tree binding document is also added for the driver. The compatible string is in compliance with Documentation/devicetree/bindings/usb/usb-device.txt Signed-off-by: Rajat Jain Reviewed-by: Brian Norris Acked-by: Rob Herring --- v5: Move the call to pm_wakeup_event() to the begining of irq handler. v4: Move the set_bit(BTUSB_OOB_WAKE_DISABLED,..) call to the beginning of btusb_config_oob_wake() v3: Add Brian's "Reviewed-by" v2: * Use interrupt-names ("wakeup") instead of assuming first interrupt. * Leave it on device tree to specify IRQ flags (level /edge triggered) * Mark the device as non wakeable on exit. Documentation/devicetree/bindings/net/btusb.txt | 40 drivers/bluetooth/btusb.c | 85 + 2 files changed, 125 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/btusb.txt diff --git a/Documentation/devicetree/bindings/net/btusb.txt b/Documentation/devicetree/bindings/net/btusb.txt new file mode 100644 index ..2c0355c85972 --- /dev/null +++ b/Documentation/devicetree/bindings/net/btusb.txt @@ -0,0 +1,40 @@ +Generic Bluetooth controller over USB (btusb driver) +--- + +Required properties: + + - compatible : should comply with the format "usbVID,PID" specified in +Documentation/devicetree/bindings/usb/usb-device.txt +At the time of writing, the only OF supported devices +(more may be added later) are: + + "usb1286,204e" (Marvell 8997) + +Optional properties: + + - interrupt-parent: phandle of the parent interrupt controller + - interrupt-names: (see below) + - interrupts : The interrupt specified by the name "wakeup" is the interrupt +that shall be used for out-of-band wake-on-bt. Driver will +request this interrupt for wakeup. During system suspend, the +irq will be enabled so that the bluetooth chip can wakeup host +platform out of band. During system resume, the irq will be +disabled to make sure unnecessary interrupt is not received. + +Example: + +Following example uses irq pin number 3 of gpio0 for out of band wake-on-bt: + +&usb_host1_ehci { +status = "okay"; +#address-cells = <1>; +#size-cells = <0>; + +mvl_bt1: bt@1 { + compatible = "usb1286,204e"; + reg = <1>; + interrupt-parent = <&gpio0>; + interrupt-name = "wakeup"; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; +}; +}; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ce22cefceed1..0a777bb407b1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -369,6 +371,7 @@ static const struct usb_device_id blacklist_table[] = { #define BTUSB_BOOTING 9 #define BTUSB_RESET_RESUME 10 #define BTUSB_DIAG_RUNNING 11 +#define BTUSB_OOB_WAKE_DISABLED12 struct btusb_data { struct hci_dev *hdev; @@ -416,6 +419,8 @@ struct btusb_data { int (*recv_bulk)(struct btusb_data *data, void *buffer, int count); int (*setup_on_usb)(struct hci_dev *hdev); + + int oob_wake_irq; /* irq for out-of-band wake-on-bt */ }; static inline void btusb_free_frags(struct btusb_data *data) @@ -2728,6 +2733,66 @@ static int btusb_bcm_set_diag(struct hci_dev *hdev, bool enable) } #endif +#ifdef CONFIG_PM +static irqreturn_t btusb_oob_wake_handler(int irq, void *priv) +{ + struct btusb_data *data = priv; + + pm_wakeup_event(&data->udev->dev, 0); + + /* Disable only if not already disabled (keep it balanced) */ + if (!test_and_set_bit(BTUSB_OOB_WAKE_DISABLED, &data->flags)) { + disable_irq_nosync(irq); + disable_irq_wake(irq); + } + return IRQ_HANDLED; +} + +static const struct of_device_id btusb_match_table[] = { + { .compatible = "usb1286,204e" }, + { } +}; +MODULE_DEVICE_TABLE(of, btusb_match_table); + +/* Use an oob wakeup pin? */ +static int btusb_config_oob_wake(struct hci_dev *hdev) +{ + struct btusb_data *data = hci_get_drvdata(hdev); + struct device *dev = &data->udev->dev; + int irq, ret; + + set_bit(BTUSB_OOB_WAKE_DISABLED, &data->flags); + + if (!of_match_device(btusb_match_table, dev)) +
Re: sysfs deferred_probe attribute
On Thu, Jan 12, 2017 at 11:27:01AM -0600, Rob Herring wrote: > I just noticed that we have a new device attribute 'deferred_probe' > added in 4.10 with this commit: > > commit 6751667a29d6fd64afb9ce30567ad616b68ed789 > Author: Ben Hutchings > Date: Tue Aug 16 14:34:18 2016 +0100 > > driver core: Add deferred_probe attribute to devices in sysfs > > It is sometimes useful to know that a device is on the deferred probe > list rather than, say, not having a driver available. Expose this > information to user-space. > > Signed-off-by: Ben Hutchings > Signed-off-by: Greg Kroah-Hartman > > > It seems like a bad idea to add an ABI for an internal kernel feature. > When/if we replace deferred probe with something better based on > functional dependencies are we going to keep this attr around? Or > remove it and assume no userspace uses it? Perhaps it should be hidden > behind CONFIG_DEBUG or just make a debugfs file that lists the > deferred list. Then you wouldn't have to hunt for what got deferred. Ah, debugfs would be nice, I'd much prefer that. I don't know how Ben is using this, but I think that would make more sense to me. thanks, greg k-h
[PATCH v5 1/3] Bluetooth: btusb: Use an error label for error paths
Use a label to remove the repetetive cleanup, for error cases. Signed-off-by: Rajat Jain Reviewed-by: Brian Norris --- v5: same as v4 v4: same as v3 v3: Added Brian's "Reviewed-by" v2: same as v1 drivers/bluetooth/btusb.c | 19 +-- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2f633df9f4e6..ce22cefceed1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2991,18 +2991,15 @@ static int btusb_probe(struct usb_interface *intf, err = usb_set_interface(data->udev, 0, 0); if (err < 0) { BT_ERR("failed to set interface 0, alt 0 %d", err); - hci_free_dev(hdev); - return err; + goto out_free_dev; } } if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, data->isoc, data); - if (err < 0) { - hci_free_dev(hdev); - return err; - } + if (err < 0) + goto out_free_dev; } #ifdef CONFIG_BT_HCIBTUSB_BCM @@ -3016,14 +3013,16 @@ static int btusb_probe(struct usb_interface *intf, #endif err = hci_register_dev(hdev); - if (err < 0) { - hci_free_dev(hdev); - return err; - } + if (err < 0) + goto out_free_dev; usb_set_intfdata(intf, data); return 0; + +out_free_dev: + hci_free_dev(hdev); + return err; } static void btusb_disconnect(struct usb_interface *intf) -- 2.11.0.390.gc69c2f50cf-goog
Re: [PATCH 1/5] perf, tools: Add probing for xed
On Thu, Jan 12, 2017 at 09:52:53AM +0100, Jiri Olsa wrote: > On Wed, Jan 11, 2017 at 02:17:56PM -0800, Andi Kleen wrote: > > > > diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature > > > > index e3fb5ecbdcb6..971a9ef87ca6 100644 > > > > --- a/tools/build/Makefile.feature > > > > +++ b/tools/build/Makefile.feature > > > > @@ -63,7 +63,7 @@ FEATURE_TESTS_BASIC := \ > > > > lzma\ > > > > get_cpuid \ > > > > bpf \ > > > > -sdt > > > > + sdt \ > > > > > > looks like you forgot to add xed in here? why the '\' ? > > > > I removed it, but incompletely. > > > > > anyway, please add it in here so it's visible under make VF=1 > > > > If I add it here then it is shown by default (even without VF=1). > > Arnaldo requested earlier that it shouldn't be shown. > > if you put it to FEATURE_TESTS_BASIC then it's displayed only for VF=1 It's already in FEATURE_TESTS_BASIC: @ -63,7 +63,8 @@ FEATURE_TESTS_BASIC := \ lzma\ get_cpuid \ bpf \ -sdt + sdt \ + xed -ANdi
Re: [PATCH 4/4] ARM: dts: sun8i: add OTG function to Lichee Pi Zero
Hi Bin, On Thu, Jan 12, 2017 at 08:50:14AM -0600, Bin Liu wrote: > On Wed, Jan 11, 2017 at 10:06:38PM +0100, Maxime Ripard wrote: > > On Wed, Jan 11, 2017 at 02:08:11PM -0600, Bin Liu wrote: > > > On Thu, Jan 12, 2017 at 03:55:33AM +0800, Icenowy Zheng wrote: > > > > > > > > > > > > 11.01.2017, 04:24, "Bin Liu" : > > > > > On Tue, Jan 03, 2017 at 11:25:34PM +0800, Icenowy Zheng wrote: > > > > >> Lichee Pi Zero features a USB OTG port. > > > > >> > > > > >> Add support for it. > > > > >> > > > > >> Note: in order to use the Host mode, the board must be powered via > > > > >> the > > > > >> +5V and GND pins. > > > > >> > > > > >> Signed-off-by: Icenowy Zheng > > > > >> --- > > > > >> arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts | 10 ++ > > > > >> 1 file changed, 10 insertions(+) > > > > >> > > > > >> diff --git a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts > > > > >> b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts > > > > >> index 0099affc6ce3..3d9168cbaeca 100644 > > > > >> --- a/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts > > > > >> +++ b/arch/arm/boot/dts/sun8i-v3s-licheepi-zero.dts > > > > >> @@ -71,3 +71,13 @@ > > > > >> pinctrl-names = "default"; > > > > >> status = "okay"; > > > > >> }; > > > > >> + > > > > >> +&usb_otg { > > > > >> + dr_mode = "otg"; > > > > > > > > > > Why not set this default mode in dtsi instead? > > > > > > > > > > Regards, > > > > > -Bin. > > > > > > > > There's possibly boards which do not have OTG functions. > > > > > > That is board specific. > > > > Exactly, and this is why it should be done in the board DT. > > I am just suggesting based on the common practice. If a .dtsi exists for > a family, the .dtsi describes the device and common properties for all > possible boards, and each board .dts adds or overrides its specific > implementation. Kernel has many devices/boards done in this way - define > the default dr_mode in .dtsi. > > In this case, I suggest to set the common dr_mode in .dtsi, then each > board .dts only overrides it if the implementation is different. > > > > > The controller in the Allwinner SoCs do not handle directly the ID pin > > and VBUS, but rather rely on a GPIO to do so. > > > > So boards with OTG will need setup anyway, at least to tell which > > GPIOs are used. There's no point in enforcing a default if it doesn't > > work by default. > > Then define a default which supposes to work for most boards. > > Why I suggest this, is because defining a default dr_mode which works > for most cases in dtsi could prevent a little surprise in MUSB function. > If someone designs a new board but forgets to define dr_mode in the new > board DT, the MUSB driver will default to org mode, which might not be > intended. The point is that there is no sensible default. Some boards don't have an ID pin and no VBUS (peripheral), some don't have an ID pin but VBUS (host), and some have an ID pin but no controllable VBUS, some have an ID pin and a controllable VBUS, but we have no idea which GPIOs are used. There's no way we can have something that works on most cases. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH 01/11] perf, tools: Factor out scale conversion code
Em Thu, Jan 12, 2017 at 10:31:57AM -0300, Arnaldo Carvalho de Melo escreveu: > Em Sun, Jan 08, 2017 at 07:57:53PM +0100, Jiri Olsa escreveu: > > On Tue, Jan 03, 2017 at 07:08:23AM -0800, Andi Kleen wrote: > > > > SNIP > > > > > - goto error; > > > - > > > - if (scale[sret - 1] == '\n') > > > - scale[sret - 1] = '\0'; > > > - else > > > - scale[sret] = '\0'; > > > + int ret = 0; > > > > > > /* > > >* save current locale > > > @@ -133,8 +111,8 @@ static int perf_pmu__parse_scale(struct > > > perf_pmu_alias *alias, char *dir, char * > > >*/ > > > lc = strdup(lc); > > > if (!lc) { > > > - ret = -ENOMEM; > > > - goto error; > > > + ret = -1; > > > + goto out; > > > > not sure why you changed the -ENOMEM to -1 ;-) but it's ok anyway > > These unrelated things are just that, noise, I'll ditch it to reduce > patch size while not introducing any functional change. But then this return is not even being looked at anywhere :-\ > > Acked-by: Jiri Olsa > > Will keep your ack tho :-) > > - Arnaldo > > > thanks, > > jirka
Re: [PATCH v2 2/2] Support for DW CSI-2 Host IPK
On 01/12/2017 06:43 PM, Ramiro Oliveira wrote: > Hi Hans, > > Thank you for your feedback. > > On 1/11/2017 11:54 AM, Hans Verkuil wrote: >> Hi Ramiro, >> >> See my review comments below: >> >> On 12/12/16 16:00, Ramiro Oliveira wrote: >>> Add support for the DesignWare CSI-2 Host IP Prototyping Kit >>> >>> Signed-off-by: Ramiro Oliveira > > [snip] >>> + >>> +static int vid_dev_subdev_s_power(struct v4l2_subdev *sd, int on) >>> +{ >>> +return 0; >>> +} >> >> Just drop this empty function, shouldn't be needed. >> > > When I start my system I'm hoping all the subdevs have s_power registered. If > it > doesn't exist should I change the way I handle it, or will the core handle it > for me? If it isn't provided, then it is just skipped. The general rule is that you only provide these ops if they do something useful. > >>> + >>> +static int vid_dev_subdev_registered(struct v4l2_subdev *sd) >>> +{ >>> +struct video_device_dev *vid_dev = v4l2_get_subdevdata(sd); >>> +struct vb2_queue *q = &vid_dev->vb_queue; >>> +struct video_device *vfd = &vid_dev->ve.vdev; >>> +int ret; >>> + >>> +memset(vfd, 0, sizeof(*vfd)); >>> + >>> +strlcpy(vfd->name, VIDEO_DEVICE_NAME, sizeof(vfd->name)); >>> + >>> +vfd->fops = &vid_dev_fops; >>> +vfd->ioctl_ops = &vid_dev_ioctl_ops; >>> +vfd->v4l2_dev = sd->v4l2_dev; >>> +vfd->minor = -1; >>> +vfd->release = video_device_release_empty; >>> +vfd->queue = q; >>> + >>> +INIT_LIST_HEAD(&vid_dev->vidq.active); >>> +init_waitqueue_head(&vid_dev->vidq.wq); >>> +memset(q, 0, sizeof(*q)); >>> +q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; >>> +q->io_modes = VB2_MMAP | VB2_USERPTR; >> >> Add VB2_DMABUF and VB2_READ. >> > > I'll add them, but I'm not using them, is it standard procedure to add them > all > even if they aren't used? You may not use them, but others might. And it doesn't cost anything to add them. > >>> +q->ops = &vb2_video_qops; >>> +q->mem_ops = &vb2_vmalloc_memops; >> >> Why is vmalloc used? Can't you use dma_contig or dma_sg and avoid having to >> copy >> the image data? That's a really bad design given the amount of video data >> that >> you have to copy. >> > > When I started development, the arch I was using (ARC) didn't support > dma_contig, so I was forced to use vmalloc. > > Since then things have changed and I'm already using dma_contig, however it > wasn't included in this patch. I'll add it to the next patch. Ah, good. If you are switching to dma_contig, then remove VB2_USERPTR. VB2_DMABUF should be used instead. Regards, Hans
Re: [PATCH] xen-netback: fix memory leaks on XenBus disconnect
On 12/01/17 17:51, Igor Druzhinin wrote: > Eliminate memory leaks introduced several years ago by cleaning the queue > resources which are allocated on XenBus connection event. Namely, queue > structure array and pages used for IO rings. > vif->lock is used to protect statistics gathering agents from using the > queue structure during cleaning. > > Signed-off-by: Igor Druzhinin > --- > drivers/net/xen-netback/interface.c | 6 -- > drivers/net/xen-netback/xenbus.c| 13 + > 2 files changed, 17 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/xen-netback/interface.c > b/drivers/net/xen-netback/interface.c > index e30ffd2..5795213 100644 > --- a/drivers/net/xen-netback/interface.c > +++ b/drivers/net/xen-netback/interface.c > @@ -221,18 +221,18 @@ static struct net_device_stats *xenvif_get_stats(struct > net_device *dev) > { > struct xenvif *vif = netdev_priv(dev); > struct xenvif_queue *queue = NULL; > - unsigned int num_queues = vif->num_queues; > unsigned long rx_bytes = 0; > unsigned long rx_packets = 0; > unsigned long tx_bytes = 0; > unsigned long tx_packets = 0; > unsigned int index; > > + spin_lock(&vif->lock); > if (vif->queues == NULL) > goto out; > > /* Aggregate tx and rx stats from each queue */ > - for (index = 0; index < num_queues; ++index) { > + for (index = 0; index < vif->num_queues; ++index) { > queue = &vif->queues[index]; > rx_bytes += queue->stats.rx_bytes; > rx_packets += queue->stats.rx_packets; > @@ -241,6 +241,8 @@ static struct net_device_stats *xenvif_get_stats(struct > net_device *dev) > } > > out: > + spin_unlock(&vif->lock); > + > vif->dev->stats.rx_bytes = rx_bytes; > vif->dev->stats.rx_packets = rx_packets; > vif->dev->stats.tx_bytes = tx_bytes; > diff --git a/drivers/net/xen-netback/xenbus.c > b/drivers/net/xen-netback/xenbus.c > index 3124eae..85b742e 100644 > --- a/drivers/net/xen-netback/xenbus.c > +++ b/drivers/net/xen-netback/xenbus.c > @@ -493,11 +493,22 @@ static int backend_create_xenvif(struct backend_info > *be) > static void backend_disconnect(struct backend_info *be) > { > if (be->vif) { > + unsigned int queue_index; > + > xen_unregister_watchers(be->vif); > #ifdef CONFIG_DEBUG_FS > xenvif_debugfs_delif(be->vif); > #endif /* CONFIG_DEBUG_FS */ > xenvif_disconnect_data(be->vif); > + for (queue_index = 0; queue_index < be->vif->num_queues; > ++queue_index) > + xenvif_deinit_queue(&be->vif->queues[queue_index]); > + > + spin_lock(&be->vif->lock); > + vfree(be->vif->queues); > + be->vif->num_queues = 0; > + be->vif->queues = NULL; > + spin_unlock(&be->vif->lock); > + > xenvif_disconnect_ctrl(be->vif); > } > } > @@ -1034,6 +1045,8 @@ static void connect(struct backend_info *be) > err: > if (be->vif->num_queues > 0) > xenvif_disconnect_data(be->vif); /* Clean up existing queues */ > + for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index) > + xenvif_deinit_queue(&be->vif->queues[queue_index]); > vfree(be->vif->queues); > be->vif->queues = NULL; > be->vif->num_queues = 0; > Add Juergen Gross to CC. Igor
master - btrfs lockdep splat
Greetings, I wanted to do some -rt testing, but seems non-rt kernels aren't lockdep clean with btrfs /, making -rt testing a bit premature. (hm, 28a235931 Btrfs: fix lockdep warning on deadlock against an inode's log mutex) [ 876.622587] = [ 876.622588] [ INFO: possible recursive locking detected ] [ 876.622589] 4.10.0-master #36 Tainted: GE [ 876.622590] - [ 876.622591] vi/3364 is trying to acquire lock: [ 876.622592] (&ei->log_mutex){+.+...}, at: [] btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622628] but task is already holding lock: [ 876.622629] (&ei->log_mutex){+.+...}, at: [] btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622641] other info that might help us debug this: [ 876.622642] Possible unsafe locking scenario: [ 876.622643]CPU0 [ 876.622644] [ 876.622644] lock(&ei->log_mutex); [ 876.622648] lock(&ei->log_mutex); [ 876.622649] *** DEADLOCK *** [ 876.622650] May be due to missing lock nesting notation [ 876.622651] 3 locks held by vi/3364: [ 876.622651] #0: (&sb->s_type->i_mutex_key#11){+.+.+.}, at: [] btrfs_sync_file+0x154/0x480 [btrfs] [ 876.622664] #1: (sb_internal){.+.+..}, at: [] start_transaction+0x2a7/0x540 [btrfs] [ 876.622674] #2: (&ei->log_mutex){+.+...}, at: [] btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622685] stack backtrace: [ 876.622687] CPU: 3 PID: 3364 Comm: vi Tainted: GE 4.10.0-master #36 [ 876.622688] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.1-0-g4adadbd-20161202_174313-build11a 04/01/2014 [ 876.622689] Call Trace: [ 876.622698] dump_stack+0x85/0xc9 [ 876.622704] __lock_acquire+0x9f9/0x1550 [ 876.622715] ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs] [ 876.622717] lock_acquire+0xbd/0x200 [ 876.622726] ? btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622732] mutex_lock_nested+0x69/0x660 [ 876.622741] ? btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622750] ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs] [ 876.622759] ? btrfs_commit_inode_delayed_inode+0xeb/0x130 [btrfs] [ 876.622767] btrfs_log_inode+0x13c/0xbd0 [btrfs] [ 876.622771] ? __might_sleep+0x4a/0x90 [ 876.622781] ? btrfs_i_callback+0x20/0x20 [btrfs] [ 876.622791] ? free_extent_buffer+0x4b/0x90 [btrfs] [ 876.622799] btrfs_log_inode+0x572/0xbd0 [btrfs] [ 876.622808] btrfs_log_inode_parent+0x26a/0x9b0 [btrfs] [ 876.622812] ? dget_parent+0x77/0x170 [ 876.622821] btrfs_log_dentry_safe+0x62/0x80 [btrfs] [ 876.622830] btrfs_sync_file+0x2eb/0x480 [btrfs] [ 876.622834] vfs_fsync_range+0x3d/0xb0 [ 876.622836] ? trace_hardirqs_on_caller+0xf9/0x1c0 [ 876.622837] do_fsync+0x3d/0x70 [ 876.622839] SyS_fsync+0x10/0x20 [ 876.622840] entry_SYSCALL_64_fastpath+0x1f/0xc2 [ 876.622842] RIP: 0033:0x7f7fbe3da290 [ 876.622843] RSP: 002b:7ffe2778f0b8 EFLAGS: 0246 ORIG_RAX: 004a [ 876.622844] RAX: ffda RBX: 0003 RCX: 7f7fbe3da290 [ 876.622845] RDX: 103d RSI: 0143e5d0 RDI: 0003 [ 876.622846] RBP: 01285f10 R08: 0143e5d0 R09: [ 876.622847] R10: R11: 0246 R12: [ 876.622847] R13: 2000 R14: 0001 R15: 012821a0
[PATCH] tpm_tis: fix iTPM probe via probe_itpm() function
probe_itpm() function is supposed to send command without an itpm flag set and if this fails to repeat it, this time with the itpm flag set. However, commit 41a5e1cf1fe15 ("tpm/tpm_tis: Split tpm_tis driver into a core and TCG TIS compliant phy") moved the itpm flag from an "itpm" variable to a TPM_TIS_ITPM_POSSIBLE chip flag, so setting the (now function-local) itpm variable no longer had any effect. Finally, this function-local itpm variable was removed by commit 56af322156dbe9 ("tpm/tpm_tis: remove unused itpm variable") Tested only on non-iTPM TIS TPM. Signed-off-by: Maciej S. Szmigiero Fixes: 41a5e1cf1fe15 ("Split tpm_tis driver into a core and TCG TIS compliant phy") Cc: sta...@vger.kernel.org --- drivers/char/tpm/tpm_tis_core.c | 25 + 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index e42e5a6a3c2f..401f1228547c 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -467,6 +467,9 @@ static int probe_itpm(struct tpm_chip *chip) size_t len = sizeof(cmd_getticks); u16 vendor; + if (priv->flags & TPM_TIS_ITPM_POSSIBLE) + return 0; + rc = tpm_tis_read16(priv, TPM_DID_VID(0), &vendor); if (rc < 0) return rc; @@ -482,12 +485,15 @@ static int probe_itpm(struct tpm_chip *chip) tpm_tis_ready(chip); release_locality(chip, priv->locality, 0); + priv->flags |= TPM_TIS_ITPM_POSSIBLE; + rc = tpm_tis_send_data(chip, cmd_getticks, len); - if (rc == 0) { + if (rc == 0) dev_info(&chip->dev, "Detected an iTPM.\n"); - rc = 1; - } else + else { + priv->flags &= ~TPM_TIS_ITPM_POSSIBLE; rc = -EFAULT; + } out: tpm_tis_ready(chip); @@ -743,15 +749,10 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", vendor >> 16, rid); - if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) { - probe = probe_itpm(chip); - if (probe < 0) { - rc = -ENODEV; - goto out_err; - } - - if (!!probe) - priv->flags |= TPM_TIS_ITPM_POSSIBLE; + probe = probe_itpm(chip); + if (probe < 0) { + rc = -ENODEV; + goto out_err; } /* Figure out the capabilities */
[PATCH] tpm_tis: override reported C and D timeouts for Atmel 3203
Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) no longer works. It turns out the initialization proceeds fine until we get and start using chip-reported timeouts - and the chip reports C and D timeouts of zero. Since these are clearly not long enough let's add an override for them to TPM TIS default values, just as we do for Atmel 3204. A and B timeouts are set to the same values as the chip normally reports. Signed-off-by: Maciej S. Szmigiero Fixes: 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM access") Cc: sta...@vger.kernel.org --- drivers/char/tpm/tpm_tis_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 7993678954a2..e42e5a6a3c2f 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -421,6 +421,9 @@ struct tis_vendor_timeout_override { }; static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = { + /* Atmel 3203 */ + { 0x32031114, { (10*1000), (10*1000), + (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, /* Atmel 3204 */ { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } },
Re: Linux 4.9.3
Still no sign of the 4.9.3 patches on the FTP site... Oops? Cheers, Chris
Nokia N900: mixers changed between 4.6 and 4.10, no longer can use in-call speaker
Hi! In v4.10 (and probably v4.9, too) I can no longer use the in-call speaker. I can no longer use the wired headset, either. v4.4 (and probably v4.6) works ok. Any ideas? Does wired headset / in-call speaker work for you? "Mono" and "Mono DAC" options are still there.. but something else changed, as alsamixer now shows way many more options (meaning they are shorter?) and I get complains from alsactl: alsactl: set_control:1328: failed to obtain info for control #49 (No such file or directory) ... alsactl: set_control:1328: failed to obtain info for control #229 (No such file or directory) Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html signature.asc Description: Digital signature
[PATCH V7 00/10] Add UEFI 2.6 and ACPI 6.1 updates for RAS on ARM64
When a memory error, CPU error, PCIe error, or other type of hardware error that's covered by RAS occurs, firmware should populate the shared GHES memory location with the proper GHES structures to notify the OS of the error. For example, platforms that implement firmware first handling may implement separate GHES sources for corrected errors and uncorrected errors. If the error is an uncorrectable error, then the firmware will notify the OS immediately since the error needs to be handled ASAP. The OS will then be able to take the appropriate action needed such as offlining a page. If the error is a corrected error, then the firmware will not interrupt the OS immediately. Instead, the OS will see and report the error the next time it's GHES timer expires. The kernel will first parse the GHES structures and report the errors through the kernel logs and then notify the user space through RAS trace events. This allows user space applications such as RAS Daemon to see the errors and report them however the user desires. This patchset extends the kernel functionality for RAS errors based on updates in the UEFI 2.6 and ACPI 6.1 specifications. An example flow from firmware to user space could be: +---+ +>| | | | GHES polling |--+ +-+ |source | | +---+ ++ | | +---+ | | Kernel GHES | || | Firmware | +-->| CPER AER and |-->| RAS trace | | | +---+ | | EDAC drivers | | event| +-+ | | | +---+ ++ | | GHES sci |--+ +>| source | +---+ Add support for Generic Hardware Error Source (GHES) v2, which introduces the capability for the OS to acknowledge the consumption of the error record generated by the Reliability, Availability and Serviceability (RAS) controller. This eliminates potential race conditions between the OS and the RAS controller. Add support for the timestamp field added to the Generic Error Data Entry v3, allowing the OS to log the time that the error is generated by the firmware, rather than the time the error is consumed. This improves the correctness of event sequences when analyzing error logs. The timestamp is added in ACPI 6.1, reference Table 18-343 Generic Error Data Entry. Add support for ARMv8 Common Platform Error Record (CPER) per UEFI 2.6 specification. ARMv8 specific processor error information is reported as part of the CPER records. This provides more detail on for processor error logs. This can help describe ARMv8 cache, tlb, and bus errors. Synchronous External Abort (SEA) represents a specific processor error condition in ARM systems. A handler is added to recognize SEA errors, and a notifier is added to parse and report the errors before the process is killed. Refer to section N.2.1.1 in the Common Platform Error Record appendix of the UEFI 2.6 specification. Currently the kernel ignores CPER records that are unrecognized. On the other hand, UEFI spec allows for non-standard (eg. vendor proprietary) error section type in CPER (Common Platform Error Record), as defined in section N2.3 of UEFI version 2.5. Therefore, user is not able to see hardware error data of non-standard section. If section Type field of Generic Error Data Entry is unrecognized, prints out the raw data in dmesg buffer, and also adds a tracepoint for reporting such hardware errors. Currently even if an error status block's severity is fatal, the kernel does not honor the severity level and panic. With the firmware first model, the platform could inform the OS about a fatal hardware error through the non-NMI GHES notification type. The OS should panic when a hardware error record is received with this severity. Add support to handle SEAs that occur while a KVM guest kernel is running. Currently these are unsupported by the guest abort handling. V7: Update a couple prints for ARM processor errors Add Print notifying if overflow occurred for ARM processor errors Check for ARM configuration to allow the compiler to ignore ARM code on non-ARM systems Use SEA acronym instead of spelling it out Update fault_info prints to be more clear Add NMI locking to SEA notification Remove error info structure from ARM trace event since there can be a variable amount of these structures V6: Change HEST_TYPE_GENERIC_V2 to IS_HEST_TYPE_GENERIC_V2 for readability Move APEI helper defines from cper.h to ghes.h Add data_len decrement back into print loop Change references to ARMv8 to just ARM Rewrite ARM processor context info parsing Check valid bit of ARM error info field before printing it Add include of linux/uuid.h in ghes.c V5: Fix GHES goto logic for error conditions Change ghes_do_read_ack to ghes_ack_error
[PATCH V7 04/10] arm64: exception: handle Synchronous External Abort
SEA exceptions are often caused by an uncorrected hardware error, and are handled when data abort and instruction abort exception classes have specific values for their Fault Status Code. When SEA occurs, before killing the process, go through the handlers registered in the notification list. Update fault_info[] with specific SEA faults so that the new SEA handler is used. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Naveen Kaje --- arch/arm64/include/asm/system_misc.h | 13 arch/arm64/mm/fault.c| 58 +--- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h index 57f110b..e7f3440 100644 --- a/arch/arm64/include/asm/system_misc.h +++ b/arch/arm64/include/asm/system_misc.h @@ -64,4 +64,17 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); #endif /* __ASSEMBLY__ */ +/* + * The functions below are used to register and unregister callbacks + * that are to be invoked when a Synchronous External Abort (SEA) + * occurs. An SEA is raised by certain fault status codes that have + * either data or instruction abort as the exception class, and + * callbacks may be registered to parse or handle such hardware errors. + * + * Registered callbacks are run in an interrupt/atomic context. They + * are not allowed to block or sleep. + */ +int register_sea_notifier(struct notifier_block *nb); +void unregister_sea_notifier(struct notifier_block *nb); + #endif /* __ASM_SYSTEM_MISC_H */ diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 05d2bd7..81039c7 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -39,6 +39,22 @@ #include #include +/* + * GHES SEA handler code may register a notifier call here to + * handle HW error record passed from platform. + */ +static ATOMIC_NOTIFIER_HEAD(sea_handler_chain); + +int register_sea_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&sea_handler_chain, nb); +} + +void unregister_sea_notifier(struct notifier_block *nb) +{ + atomic_notifier_chain_unregister(&sea_handler_chain, nb); +} + static const char *fault_name(unsigned int esr); #ifdef CONFIG_KPROBES @@ -480,6 +496,28 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) return 1; } +/* + * This abort handler deals with Synchronous External Abort. + * It calls notifiers, and then returns "fault". + */ +static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) +{ + struct siginfo info; + + atomic_notifier_call_chain(&sea_handler_chain, 0, NULL); + + pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n", +fault_name(esr), esr, addr); + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = 0; + info.si_addr = (void __user *)addr; + arm64_notify_die("", regs, &info, esr); + + return 0; +} + static const struct fault_info { int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs); int sig; @@ -502,22 +540,22 @@ static const struct fault_info { { do_page_fault,SIGSEGV, SEGV_ACCERR, "level 1 permission fault" }, { do_page_fault,SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, { do_page_fault,SIGSEGV, SEGV_ACCERR, "level 3 permission fault" }, - { do_bad, SIGBUS, 0, "synchronous external abort"}, + { do_sea, SIGBUS, 0, "synchronous external abort"}, { do_bad, SIGBUS, 0, "unknown 17" }, { do_bad, SIGBUS, 0, "unknown 18" }, { do_bad, SIGBUS, 0, "unknown 19" }, - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, - { do_bad, SIGBUS, 0, "synchronous abort (translation table walk)" }, - { do_bad, SIGBUS, 0, "synchronous parity error" }, + { do_sea, SIGBUS, 0, "level 0 SEA (translation table walk)" }, + { do_sea, SIGBUS, 0, "level 1 SEA (translation table walk)" }, + { do_sea, SIGBUS, 0, "level 2 SEA (translation table walk)" }, + { do_sea, SIGBUS, 0, "level 3 SEA (translation table walk)" }, + { do_sea, SIGBUS, 0, "synchronous parity or ECC err" },
[PATCH V7 01/10] acpi: apei: read ack upon ghes record consumption
A RAS (Reliability, Availability, Serviceability) controller may be a separate processor running in parallel with OS execution, and may generate error records for consumption by the OS. If the RAS controller produces multiple error records, then they may be overwritten before the OS has consumed them. The Generic Hardware Error Source (GHES) v2 structure introduces the capability for the OS to acknowledge the consumption of the error record generated by the RAS controller. A RAS controller supporting GHESv2 shall wait for the acknowledgment before writing a new error record, thus eliminating the race condition. Add support for parsing of GHESv2 sub-tables as well. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Richard Ruigrok Signed-off-by: Naveen Kaje Reviewed-by: James Morse --- drivers/acpi/apei/ghes.c | 49 +--- drivers/acpi/apei/hest.c | 7 +-- include/acpi/ghes.h | 5 - 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 60746ef..b23160d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -45,6 +45,7 @@ #include #include +#include #include #include #include @@ -79,6 +80,10 @@ ((struct acpi_hest_generic_status *)\ ((struct ghes_estatus_node *)(estatus_node) + 1)) +#define IS_HEST_TYPE_GENERIC_V2(ghes) \ + ((struct acpi_hest_header *)ghes->generic)->type == \ +ACPI_HEST_TYPE_GENERIC_ERROR_V2 + /* * This driver isn't really modular, however for the time being, * continuing to use module_param is the easiest way to remain @@ -248,10 +253,18 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); if (!ghes) return ERR_PTR(-ENOMEM); + ghes->generic = generic; + if (IS_HEST_TYPE_GENERIC_V2(ghes)) { + rc = apei_map_generic_address( + &ghes->generic_v2->read_ack_register); + if (rc) + goto err_free; + } + rc = apei_map_generic_address(&generic->error_status_address); if (rc) - goto err_free; + goto err_unmap_read_ack_addr; error_block_length = generic->error_block_length; if (error_block_length > GHES_ESTATUS_MAX_SIZE) { pr_warning(FW_WARN GHES_PFX @@ -263,13 +276,17 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) ghes->estatus = kmalloc(error_block_length, GFP_KERNEL); if (!ghes->estatus) { rc = -ENOMEM; - goto err_unmap; + goto err_unmap_status_addr; } return ghes; -err_unmap: +err_unmap_status_addr: apei_unmap_generic_address(&generic->error_status_address); +err_unmap_read_ack_addr: + if (IS_HEST_TYPE_GENERIC_V2(ghes)) + apei_unmap_generic_address( + &ghes->generic_v2->read_ack_register); err_free: kfree(ghes); return ERR_PTR(rc); @@ -279,6 +296,9 @@ static void ghes_fini(struct ghes *ghes) { kfree(ghes->estatus); apei_unmap_generic_address(&ghes->generic->error_status_address); + if (IS_HEST_TYPE_GENERIC_V2(ghes)) + apei_unmap_generic_address( + &ghes->generic_v2->read_ack_register); } static inline int ghes_severity(int severity) @@ -648,6 +668,23 @@ static void ghes_estatus_cache_add( rcu_read_unlock(); } +static int ghes_ack_error(struct acpi_hest_generic_v2 *generic_v2) +{ + int rc; + u64 val = 0; + + rc = apei_read(&val, &generic_v2->read_ack_register); + if (rc) + return rc; + val &= generic_v2->read_ack_preserve << + generic_v2->read_ack_register.bit_offset; + val |= generic_v2->read_ack_write << + generic_v2->read_ack_register.bit_offset; + rc = apei_write(val, &generic_v2->read_ack_register); + + return rc; +} + static int ghes_proc(struct ghes *ghes) { int rc; @@ -660,6 +697,12 @@ static int ghes_proc(struct ghes *ghes) ghes_estatus_cache_add(ghes->generic, ghes->estatus); } ghes_do_proc(ghes, ghes->estatus); + + if (IS_HEST_TYPE_GENERIC_V2(ghes)) { + rc = ghes_ack_error(ghes->generic_v2); + if (rc) + return rc; + } out: ghes_clear_estatus(ghes); return 0; diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 792a0d9..ef725a9 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -52,6 +52,7 @@ static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { [ACPI_HEST_TYPE_AER_ENDPOINT] = sizeof(struct acpi_hest_aer), [ACPI_HEST_TYPE_AER_BRIDGE]
[PATCH V7 02/10] ras: acpi/apei: cper: generic error data entry v3 per ACPI 6.1
Currently when a RAS error is reported it is not timestamped. The ACPI 6.1 spec adds the timestamp field to the generic error data entry v3 structure. The timestamp of when the firmware generated the error is now being reported. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Richard Ruigrok Signed-off-by: Naveen Kaje Reviewed-by: James Morse --- drivers/acpi/apei/ghes.c| 9 --- drivers/firmware/efi/cper.c | 63 +++-- include/acpi/ghes.h | 22 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index b23160d..2acbc60 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -420,7 +420,8 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int int flags = -1; int sec_sev = ghes_severity(gdata->error_severity); struct cper_sec_mem_err *mem_err; - mem_err = (struct cper_sec_mem_err *)(gdata + 1); + + mem_err = acpi_hest_generic_data_payload(gdata); if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) return; @@ -457,7 +458,8 @@ static void ghes_do_proc(struct ghes *ghes, if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, CPER_SEC_PLATFORM_MEM)) { struct cper_sec_mem_err *mem_err; - mem_err = (struct cper_sec_mem_err *)(gdata+1); + + mem_err = acpi_hest_generic_data_payload(gdata); ghes_edac_report_mem_error(ghes, sev, mem_err); arch_apei_report_mem_error(sev, mem_err); @@ -467,7 +469,8 @@ static void ghes_do_proc(struct ghes *ghes, else if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, CPER_SEC_PCIE)) { struct cper_sec_pcie *pcie_err; - pcie_err = (struct cper_sec_pcie *)(gdata+1); + + pcie_err = acpi_hest_generic_data_payload(gdata); if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE && pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index d425374..8fa4e23 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -32,6 +32,9 @@ #include #include #include +#include +#include +#include #define INDENT_SP " " @@ -386,13 +389,37 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, pfx, pcie->bridge.secondary_status, pcie->bridge.control); } +static void cper_estatus_print_section_v300(const char *pfx, + const struct acpi_hest_generic_data_v300 *gdata) +{ + __u8 hour, min, sec, day, mon, year, century, *timestamp; + + if (gdata->validation_bits & ACPI_HEST_GEN_VALID_TIMESTAMP) { + timestamp = (__u8 *)&(gdata->time_stamp); + sec = bcd2bin(timestamp[0]); + min = bcd2bin(timestamp[1]); + hour = bcd2bin(timestamp[2]); + day = bcd2bin(timestamp[4]); + mon = bcd2bin(timestamp[5]); + year = bcd2bin(timestamp[6]); + century = bcd2bin(timestamp[7]); + printk("%stime: %7s %02d%02d-%02d-%02d %02d:%02d:%02d\n", pfx, + 0x01 & *(timestamp + 3) ? "precise" : "", century, + year, mon, day, hour, min, sec); + } +} + static void cper_estatus_print_section( - const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no) + const char *pfx, struct acpi_hest_generic_data *gdata, int sec_no) { uuid_le *sec_type = (uuid_le *)gdata->section_type; __u16 severity; char newpfx[64]; + if (acpi_hest_generic_data_version(gdata) >= 3) + cper_estatus_print_section_v300(pfx, + (const struct acpi_hest_generic_data_v300 *)gdata); + severity = gdata->error_severity; printk("%s""Error %d, type: %s\n", pfx, sec_no, cper_severity_str(severity)); @@ -403,14 +430,18 @@ static void cper_estatus_print_section( snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP); if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) { - struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1); + struct cper_sec_proc_generic *proc_err; + + proc_err = acpi_hest_generic_data_payload(gdata); printk("%s""section_type: general processor error\n", newpfx); if (gdata->error_data_length >= sizeof(*proc_err)) cper_print_proc_generic(newpfx, proc_err); else goto err_section_too_small; } els
[PATCH V7 05/10] acpi: apei: handle SEA notification type for ARMv8
ARM APEI extension proposal added SEA (Synchrounous External Abort) notification type for ARMv8. Add a new GHES error source handling function for SEA. If an error source's notification type is SEA, then this function can be registered into the SEA exception handler. That way GHES will parse and report SEA exceptions when they occur. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Naveen Kaje --- arch/arm64/Kconfig| 2 ++ drivers/acpi/apei/Kconfig | 14 drivers/acpi/apei/ghes.c | 84 +++ 3 files changed, 100 insertions(+) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index b380c87..0465601 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -53,6 +53,8 @@ config ARM64 select HANDLE_DOMAIN_IRQ select HARDIRQS_SW_RESEND select HAVE_ACPI_APEI if (ACPI && EFI) + select HAVE_ACPI_APEI_SEA if (ACPI && EFI) + select HAVE_NMI if HAVE_ACPI_APEI_SEA select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_BITREVERSE diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index b0140c8..3786ff1 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig @@ -4,6 +4,20 @@ config HAVE_ACPI_APEI config HAVE_ACPI_APEI_NMI bool +config HAVE_ACPI_APEI_SEA + bool "APEI Synchronous External Abort logging/recovering support" + depends on ARM64 + help + This option should be enabled if the system supports + firmware first handling of SEA (Synchronous External Abort). + SEA happens with certain faults of data abort or instruction + abort synchronous exceptions on ARMv8 systems. If a system + supports firmware first handling of SEA, the platform analyzes + and handles hardware error notifications with SEA, and it may then + form a HW error record for the OS to parse and handle. This + option allows the OS to look for such HW error record, and + take appropriate action. + config ACPI_APEI bool "ACPI Platform Error Interface (APEI)" select MISC_FILESYSTEMS diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 2acbc60..87efe26 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -44,12 +44,17 @@ #include #include #include +#include #include #include #include #include +#ifdef CONFIG_HAVE_ACPI_APEI_SEA +#include +#endif + #include "apei-internal.h" #define GHES_PFX "GHES: " @@ -767,6 +772,62 @@ static struct notifier_block ghes_notifier_sci = { .notifier_call = ghes_notify_sci, }; +#ifdef CONFIG_HAVE_ACPI_APEI_SEA +static LIST_HEAD(ghes_sea); + +static int ghes_notify_sea(struct notifier_block *this, + unsigned long event, void *data) +{ + struct ghes *ghes; + int ret = NOTIFY_DONE; + + nmi_enter(); + list_for_each_entry_rcu(ghes, &ghes_sea, list) { + if (!ghes_proc(ghes)) + ret = NOTIFY_OK; + } + nmi_exit(); + + return ret; +} + +static struct notifier_block ghes_notifier_sea = { + .notifier_call = ghes_notify_sea, +}; + +static int ghes_sea_add(struct ghes *ghes) +{ + mutex_lock(&ghes_list_mutex); + if (list_empty(&ghes_sea)) + register_sea_notifier(&ghes_notifier_sea); + list_add_rcu(&ghes->list, &ghes_sea); + mutex_unlock(&ghes_list_mutex); + return 0; +} + +static void ghes_sea_remove(struct ghes *ghes) +{ + mutex_lock(&ghes_list_mutex); + list_del_rcu(&ghes->list); + if (list_empty(&ghes_sea)) + unregister_sea_notifier(&ghes_notifier_sea); + mutex_unlock(&ghes_list_mutex); +} +#else /* CONFIG_HAVE_ACPI_APEI_SEA */ +static inline int ghes_sea_add(struct ghes *ghes) +{ + pr_err(GHES_PFX "ID: %d, trying to add SEA notification which is not supported\n", + ghes->generic->header.source_id); + return -ENOTSUPP; +} + +static inline void ghes_sea_remove(struct ghes *ghes) +{ + pr_err(GHES_PFX "ID: %d, trying to remove SEA notification which is not supported\n", + ghes->generic->header.source_id); +} +#endif /* CONFIG_HAVE_ACPI_APEI_SEA */ + #ifdef CONFIG_HAVE_ACPI_APEI_NMI /* * printk is not safe in NMI context. So in NMI handler, we allocate @@ -1011,6 +1072,14 @@ static int ghes_probe(struct platform_device *ghes_dev) case ACPI_HEST_NOTIFY_EXTERNAL: case ACPI_HEST_NOTIFY_SCI: break; + case ACPI_HEST_NOTIFY_SEA: + if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_SEA)) { + pr_warn(GHES_PFX "Generic hardware error source: %d notified via SEA is not supported\n", + generic->header.source_id); + rc = -ENOTSUPP; + goto err; + }
Re: [Intel-gfx] [PATCH v6] drm/i915: Use __sg_alloc_table_from_pages for userptr allocations
Hi Tvrtko, [auto build test ERROR on drm-intel/for-linux-next] [also build test ERROR on next-20170111] [cannot apply to v4.10-rc3] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Tvrtko-Ursulin/drm-i915-Use-__sg_alloc_table_from_pages-for-userptr-allocations/20170113-004619 base: git://anongit.freedesktop.org/drm-intel for-linux-next config: x86_64-rhel (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): In file included from drivers/gpu/drm/i915/i915_drv.c:48:0: drivers/gpu/drm/i915/i915_drv.h: In function 'i915_sg_segment_size': >> drivers/gpu/drm/i915/i915_drv.h:2605:10: error: 'SCATTERLIST_MAX_SEGMENT' >> undeclared (first use in this function) return SCATTERLIST_MAX_SEGMENT; ^~~ drivers/gpu/drm/i915/i915_drv.h:2605:10: note: each undeclared identifier is reported only once for each function it appears in -- In file included from drivers/gpu/drm/i915/i915_gem_userptr.c:27:0: drivers/gpu/drm/i915/i915_drv.h: In function 'i915_sg_segment_size': >> drivers/gpu/drm/i915/i915_drv.h:2605:10: error: 'SCATTERLIST_MAX_SEGMENT' >> undeclared (first use in this function) return SCATTERLIST_MAX_SEGMENT; ^~~ drivers/gpu/drm/i915/i915_drv.h:2605:10: note: each undeclared identifier is reported only once for each function it appears in drivers/gpu/drm/i915/i915_gem_userptr.c: In function '__i915_gem_userptr_alloc_pages': >> drivers/gpu/drm/i915/i915_gem_userptr.c:406:8: error: implicit declaration >> of function '__sg_alloc_table_from_pages' >> [-Werror=implicit-function-declaration] ret = __sg_alloc_table_from_pages(st, pvec, num_pages, ^~~ cc1: some warnings being treated as errors vim +/SCATTERLIST_MAX_SEGMENT +2605 drivers/gpu/drm/i915/i915_drv.h 2599 2600 static inline unsigned int i915_sg_segment_size(void) 2601 { 2602 unsigned int size = swiotlb_max_segment(); 2603 2604 if (size == 0) > 2605 return SCATTERLIST_MAX_SEGMENT; 2606 2607 size = rounddown(size, PAGE_SIZE); 2608 /* swiotlb_max_segment_size can return 1 byte when it means one page. */ --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH V7 06/10] acpi: apei: panic OS with fatal error status block
From: "Jonathan (Zhixiong) Zhang" Even if an error status block's severity is fatal, the kernel does not honor the severity level and panic. With the firmware first model, the platform could inform the OS about a fatal hardware error through the non-NMI GHES notification type. The OS should panic when a hardware error record is received with this severity. Call panic() after CPER data in error status block is printed if severity is fatal, before each error section is handled. Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Tyler Baicar --- drivers/acpi/apei/ghes.c | 19 ++- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 87efe26..4e9a20d 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -142,6 +142,8 @@ static unsigned long ghes_estatus_pool_size_request; static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; static atomic_t ghes_estatus_cache_alloced; +static int ghes_panic_timeout __read_mostly = 30; + static int ghes_ioremap_init(void) { ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, @@ -693,6 +695,13 @@ static int ghes_ack_error(struct acpi_hest_generic_v2 *generic_v2) return rc; } +static void __ghes_call_panic(void) +{ + if (panic_timeout == 0) + panic_timeout = ghes_panic_timeout; + panic("Fatal hardware error!"); +} + static int ghes_proc(struct ghes *ghes) { int rc; @@ -704,6 +713,10 @@ static int ghes_proc(struct ghes *ghes) if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) ghes_estatus_cache_add(ghes->generic, ghes->estatus); } + if (ghes_severity(ghes->estatus->error_severity) >= GHES_SEV_PANIC) { + __ghes_call_panic(); + } + ghes_do_proc(ghes, ghes->estatus); if (IS_HEST_TYPE_GENERIC_V2(ghes)) { @@ -848,8 +861,6 @@ static atomic_t ghes_in_nmi = ATOMIC_INIT(0); static LIST_HEAD(ghes_nmi); -static int ghes_panic_timeout __read_mostly = 30; - static void ghes_proc_in_irq(struct irq_work *irq_work) { struct llist_node *llnode, *next; @@ -942,9 +953,7 @@ static void __ghes_panic(struct ghes *ghes) __ghes_print_estatus(KERN_EMERG, ghes->generic, ghes->estatus); /* reboot to log the error! */ - if (panic_timeout == 0) - panic_timeout = ghes_panic_timeout; - panic("Fatal hardware error!"); + __ghes_call_panic(); } static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) -- Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
[PATCH V7 03/10] efi: parse ARM processor error
Add support for ARM Common Platform Error Record (CPER). UEFI 2.6 specification adds support for ARM specific processor error information to be reported as part of the CPER records. This provides more detail on for processor error logs. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang Signed-off-by: Naveen Kaje Reviewed-by: James Morse --- drivers/firmware/efi/cper.c | 133 include/linux/cper.h| 54 ++ 2 files changed, 187 insertions(+) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 8fa4e23..c2b0a12 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -110,12 +110,15 @@ void cper_print_bits(const char *pfx, unsigned int bits, static const char * const proc_type_strs[] = { "IA32/X64", "IA64", + "ARM", }; static const char * const proc_isa_strs[] = { "IA32", "IA64", "X64", + "ARM A32/T32", + "ARM A64", }; static const char * const proc_error_type_strs[] = { @@ -139,6 +142,18 @@ static const char * const proc_flag_strs[] = { "corrected", }; +static const char * const arm_reg_ctx_strs[] = { + "AArch32 general purpose registers", + "AArch32 EL1 context registers", + "AArch32 EL2 context registers", + "AArch32 secure context registers", + "AArch64 general purpose registers", + "AArch64 EL1 context registers", + "AArch64 EL2 context registers", + "AArch64 EL3 context registers", + "Misc. system register structure", +}; + static void cper_print_proc_generic(const char *pfx, const struct cper_sec_proc_generic *proc) { @@ -184,6 +199,114 @@ static void cper_print_proc_generic(const char *pfx, printk("%s""IP: 0x%016llx\n", pfx, proc->ip); } +static void cper_print_proc_arm(const char *pfx, + const struct cper_sec_proc_arm *proc) +{ + int i, len, max_ctx_type; + struct cper_arm_err_info *err_info; + struct cper_arm_ctx_info *ctx_info; + char newpfx[64]; + + printk("%s""section length: %d\n", pfx, proc->section_length); + printk("%s""MIDR: 0x%016llx\n", pfx, proc->midr); + + len = proc->section_length - (sizeof(*proc) + + proc->err_info_num * (sizeof(*err_info))); + if (len < 0) { + printk("%s""section length is too small\n", pfx); + printk("%s""firmware-generated error record is incorrect\n", pfx); + printk("%s""ERR_INFO_NUM is %d\n", pfx, proc->err_info_num); + return; + } + + if (proc->validation_bits & CPER_ARM_VALID_MPIDR) + printk("%s""MPIDR: 0x%016llx\n", pfx, proc->mpidr); + if (proc->validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL) + printk("%s""error affinity level: %d\n", pfx, + proc->affinity_level); + if (proc->validation_bits & CPER_ARM_VALID_RUNNING_STATE) { + printk("%s""running state: 0x%x\n", pfx, proc->running_state); + printk("%s""PSCI state: %d\n", pfx, proc->psci_state); + } + + snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP); + + err_info = (struct cper_arm_err_info *)(proc + 1); + for (i = 0; i < proc->err_info_num; i++) { + printk("%s""Error info structure %d:\n", pfx, i); + printk("%s""version:%d\n", newpfx, err_info->version); + printk("%s""length:%d\n", newpfx, err_info->length); + if (err_info->validation_bits & + CPER_ARM_INFO_VALID_MULTI_ERR) { + if (err_info->multiple_error == 0) + printk("%s""single error\n", newpfx); + else if (err_info->multiple_error == 1) + printk("%s""multiple errors\n", newpfx); + else + printk("%s""multiple errors count:%u\n", + newpfx, err_info->multiple_error); + } + if (err_info->validation_bits & CPER_ARM_INFO_VALID_FLAGS) { + if (err_info->flags & CPER_ARM_INFO_FLAGS_FIRST) + printk("%s""first error captured\n", newpfx); + if (err_info->flags & CPER_ARM_INFO_FLAGS_LAST) + printk("%s""last error captured\n", newpfx); + if (err_info->flags & CPER_ARM_INFO_FLAGS_PROPAGATED) + printk("%s""propagated error captured\n", + newpfx); + if (err_info->flags & CPER_ARM_INFO_FLAGS_OVERFLOW) + printk("%s""overflow occurred, error info is incomplete\n", + newpfx); + } + pr
Re: [PATCH] Input: silead: use msleep() for long delays
On Thu, Jan 12, 2017 at 9:46 AM, Hans de Goede wrote: > Hi, > > On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote: >> >> the delays here are in the 10 to 20ms range so msleep() will do - no >> need to burden the highres timer subsystem. >> >> Signed-off-by: Nicholas Mc Guire >> --- >> >> Problem found by coccinelle script >> >> While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems) >> this seems ok here as the delays are not called frequently (init and >> reset functions) > > > By the same logic, this is not much of a burden on the high-res timer > subsys though. > >> and the uncertainty of 10ms fits the permitted range of >> the original usleep_ranges(). > > > Either way this patch is fine with me. I'd rather not because next will come a checkpatch warrior and I will have to convince them why msleep is OK here. And another one, and another one... :( Thanks. -- Dmitry
[PATCH V7 09/10] trace, ras: add ARM processor error trace event
Currently there are trace events for the various RAS errors with the exception of ARM processor type errors. Add a new trace event for such errors so that the user will know when they occur. These trace events are consistent with the ARM processor error section type defined in UEFI 2.6 spec section N.2.4.4. Signed-off-by: Tyler Baicar Acked-by: Steven Rostedt --- drivers/acpi/apei/ghes.c| 7 ++- drivers/firmware/efi/cper.c | 1 + drivers/ras/ras.c | 1 + include/ras/ras_event.h | 34 ++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index a32c1b1..324a032 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -518,7 +518,12 @@ static void ghes_do_proc(struct ghes *ghes, } #endif - else { + else if (!uuid_le_cmp(sec_type, CPER_SEC_PROC_ARM)) { + struct cper_sec_proc_arm *arm_err; + + arm_err = acpi_hest_generic_data_payload(gdata); + trace_arm_event(arm_err); + } else { void *unknown_err = acpi_hest_generic_data_payload(gdata); trace_unknown_sec_event(&sec_type, fru_id, fru_text, sec_sev, diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index 48cb8ee..0ec678e 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -35,6 +35,7 @@ #include #include #include +#include #define INDENT_SP " " diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c index fb2500b..8ba5a94 100644 --- a/drivers/ras/ras.c +++ b/drivers/ras/ras.c @@ -28,3 +28,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event); #endif EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event); EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event); +EXPORT_TRACEPOINT_SYMBOL_GPL(arm_event); diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h index 5861b6f..b36db48 100644 --- a/include/ras/ras_event.h +++ b/include/ras/ras_event.h @@ -162,6 +162,40 @@ TRACE_EVENT(mc_event, ); /* + * ARM Processor Events Report + * + * This event is generated when hardware detects an ARM processor error + * has occurred. UEFI 2.6 spec section N.2.4.4. + */ +TRACE_EVENT(arm_event, + + TP_PROTO(const struct cper_sec_proc_arm *proc), + + TP_ARGS(proc), + + TP_STRUCT__entry( + __field(u64, mpidr) + __field(u64, midr) + __field(u32, running_state) + __field(u32, psci_state) + __field(u8, affinity) + ), + + TP_fast_assign( + __entry->affinity = proc->affinity_level; + __entry->mpidr = proc->mpidr; + __entry->midr = proc->midr; + __entry->running_state = proc->running_state; + __entry->psci_state = proc->psci_state; + ), + + TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " + "running state: %d; PSCI state: %d", + __entry->affinity, __entry->mpidr, __entry->midr, + __entry->running_state, __entry->psci_state) +); + +/* * Unknown Section Report * * This event is generated when hardware detected a hardware -- Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote: > The current TPM 2.0 device driver extends only the SHA1 PCR bank > but the TCG Specification[1] recommends extending all active PCR > banks, to prevent malicious users from setting unused PCR banks with > fake measurements and quoting them. > > The existing in-kernel interface(tpm_pcr_extend()) expects only a > SHA1 digest. To extend all active PCR banks with differing > digest sizes, the SHA1 digest is padded with trailing 0's as needed. > > [1] TPM 2.0 Specification referred here is "TCG PC Client Specific > Platform Firmware Profile for TPM 2.0" > > Signed-off-by: Nayna Jain > --- > drivers/char/tpm/Kconfig | 1 + > drivers/char/tpm/tpm-interface.c | 16 +- > drivers/char/tpm/tpm.h | 3 +- > drivers/char/tpm/tpm2-cmd.c | 68 > +++- > drivers/char/tpm/tpm_eventlog.h | 18 +++ > 5 files changed, 75 insertions(+), 31 deletions(-) > > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig > index 277186d..af985cc 100644 > --- a/drivers/char/tpm/Kconfig > +++ b/drivers/char/tpm/Kconfig > @@ -6,6 +6,7 @@ menuconfig TCG_TPM > tristate "TPM Hardware Support" > depends on HAS_IOMEM > select SECURITYFS > + select CRYPTO_HASH_INFO In the commit message you did not mention this. > ---help--- > If you have a TPM security chip in your system, which > implements the Trusted Computing Group's specification, > diff --git a/drivers/char/tpm/tpm-interface.c > b/drivers/char/tpm/tpm-interface.c > index fecdd3f..e037dd2 100644 > --- a/drivers/char/tpm/tpm-interface.c > +++ b/drivers/char/tpm/tpm-interface.c > @@ -7,6 +7,7 @@ > * Dave Safford > * Reiner Sailer > * Kylene Hall > + * Nayna Jain Remove. > * > * Maintained by: > * > @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = { > int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) > { > struct tpm_cmd_t cmd; > + int i; > int rc; > struct tpm_chip *chip; > > @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 > *hash) > return -ENODEV; > > if (chip->flags & TPM_CHIP_FLAG_TPM2) { > - rc = tpm2_pcr_extend(chip, pcr_idx, hash); > + struct tpml_digest_values d_values; > + > + memset(&d_values, 0, sizeof(d_values)); > + > + for (i = 0; (chip->active_banks[i] != 0) && > + (i < ARRAY_SIZE(chip->active_banks)); i++) { > + d_values.digests[i].alg_id = chip->active_banks[i]; > + memcpy(d_values.digests[i].digest, hash, > +TPM_DIGEST_SIZE); > + d_values.count++; > + } > + > + rc = tpm2_pcr_extend(chip, pcr_idx, &d_values); > tpm_put_ops(chip); > return rc; > } > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h > index 573..dd82d58 100644 > --- a/drivers/char/tpm/tpm.h > +++ b/drivers/char/tpm/tpm.h > @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip) > #endif > > int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); > -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); > +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, > + struct tpml_digest_values *digests); > int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max); > int tpm2_seal_trusted(struct tpm_chip *chip, > struct trusted_key_payload *payload, > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c > index 87388921..5027a54 100644 > --- a/drivers/char/tpm/tpm2-cmd.c > +++ b/drivers/char/tpm/tpm2-cmd.c > @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in { > __be32 pcr_idx; > __be32 auth_area_size; > struct tpm2_null_auth_area auth_area; > - __be32 digest_cnt; > - __be16 hash_alg; > - u8 digest[TPM_DIGEST_SIZE]; > + struct tpml_digest_values digests; > } __packed; > > struct tpm2_get_tpm_pt_in { > @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, > u8 *res_buf) > return rc; > } > > -#define TPM2_GET_PCREXTEND_IN_SIZE \ > - (sizeof(struct tpm_input_header) + \ > - sizeof(struct tpm2_pcr_extend_in)) > - > -static const struct tpm_input_header tpm2_pcrextend_header = { > - .tag = cpu_to_be16(TPM2_ST_SESSIONS), > - .length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE), > - .ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND) > -}; > - > /** > * tpm2_pcr_extend() - extend a PCR value > * > * @chip:TPM chip to use. > * @pcr_idx: index of the PCR. > - * @hash:hash value to use for the extend operation. > + * @digests: list of p
[PATCH V7 10/10] arm/arm64: KVM: add guest SEA support
Currently external aborts are unsupported by the guest abort handling. Add handling for SEAs so that the host kernel reports SEAs which occur in the guest kernel. Signed-off-by: Tyler Baicar --- arch/arm/include/asm/kvm_arm.h | 1 + arch/arm/include/asm/system_misc.h | 5 + arch/arm/kvm/mmu.c | 18 -- arch/arm64/include/asm/kvm_arm.h | 1 + arch/arm64/include/asm/system_misc.h | 2 ++ arch/arm64/mm/fault.c| 13 + 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h index e22089f..33a77509 100644 --- a/arch/arm/include/asm/kvm_arm.h +++ b/arch/arm/include/asm/kvm_arm.h @@ -187,6 +187,7 @@ #define FSC_FAULT (0x04) #define FSC_ACCESS (0x08) #define FSC_PERM (0x0c) +#define FSC_EXTABT (0x10) /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ #define HPFAR_MASK (~0xf) diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h index a3d61ad..ea45d94 100644 --- a/arch/arm/include/asm/system_misc.h +++ b/arch/arm/include/asm/system_misc.h @@ -24,4 +24,9 @@ extern unsigned int user_debug; #endif /* !__ASSEMBLY__ */ +static inline int handle_guest_sea(unsigned long addr, unsigned int esr) +{ + return -1; +} + #endif /* __ASM_ARM_SYSTEM_MISC_H */ diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index e9a5c0e..1152966 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "trace.h" @@ -1441,8 +1442,21 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) /* Check the stage-2 fault is trans. fault or write fault */ fault_status = kvm_vcpu_trap_get_fault_type(vcpu); - if (fault_status != FSC_FAULT && fault_status != FSC_PERM && - fault_status != FSC_ACCESS) { + + /* The host kernel will handle the synchronous external abort. There +* is no need to pass the error into the guest. +*/ + if (fault_status == FSC_EXTABT) { + if(handle_guest_sea((unsigned long)fault_ipa, + kvm_vcpu_get_hsr(vcpu))) { + kvm_err("Failed to handle guest SEA, FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", + kvm_vcpu_trap_get_class(vcpu), + (unsigned long)kvm_vcpu_trap_get_fault(vcpu), + (unsigned long)kvm_vcpu_get_hsr(vcpu)); + return -EFAULT; + } + } else if (fault_status != FSC_FAULT && fault_status != FSC_PERM && + fault_status != FSC_ACCESS) { kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", kvm_vcpu_trap_get_class(vcpu), (unsigned long)kvm_vcpu_trap_get_fault(vcpu), diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 4b5c977..be0efb6 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -201,6 +201,7 @@ #define FSC_FAULT ESR_ELx_FSC_FAULT #define FSC_ACCESS ESR_ELx_FSC_ACCESS #define FSC_PERM ESR_ELx_FSC_PERM +#define FSC_EXTABT ESR_ELx_FSC_EXTABT /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ #define HPFAR_MASK (~UL(0xf)) diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h index e7f3440..27816cb 100644 --- a/arch/arm64/include/asm/system_misc.h +++ b/arch/arm64/include/asm/system_misc.h @@ -77,4 +77,6 @@ extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd); int register_sea_notifier(struct notifier_block *nb); void unregister_sea_notifier(struct notifier_block *nb); +int handle_guest_sea(unsigned long addr, unsigned int esr); + #endif /* __ASM_SYSTEM_MISC_H */ diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 81039c7..fa8d4d7 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -597,6 +597,19 @@ static const char *fault_name(unsigned int esr) } /* + * Handle Synchronous External Aborts that occur in a guest kernel. + */ +int handle_guest_sea(unsigned long addr, unsigned int esr) +{ + atomic_notifier_call_chain(&sea_handler_chain, 0, NULL); + + pr_err("Synchronous External Abort: %s (0x%08x) at 0x%016lx\n", + fault_name(esr), esr, addr); + + return 0; +} + +/* * Dispatch a data abort to the relevant handler. */ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, -- Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
[PATCH V7 08/10] ras: acpi / apei: generate trace event for unrecognized CPER section
UEFI spec allows for non-standard section in Common Platform Error Record. This is defined in section N.2.3 of UEFI version 2.5. Currently if the CPER section's type (UUID) does not match with any section type that the kernel knows how to parse, trace event is not generated for such section. And thus user is not able to know happening of such hardware error, including error record of non-standard section. This commit generates a trace event which contains raw error data for unrecognized CPER section. Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang --- drivers/acpi/apei/ghes.c | 22 -- drivers/ras/ras.c| 1 + include/ras/ras_event.h | 45 + 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 4e9a20d..a32c1b1 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -45,11 +45,13 @@ #include #include #include +#include #include #include #include #include +#include #ifdef CONFIG_HAVE_ACPI_APEI_SEA #include @@ -458,11 +460,21 @@ static void ghes_do_proc(struct ghes *ghes, { int sev, sec_sev; struct acpi_hest_generic_data *gdata; + uuid_le sec_type; + uuid_le *fru_id = &NULL_UUID_LE; + char *fru_text = ""; sev = ghes_severity(estatus->error_severity); apei_estatus_for_each_section(estatus, gdata) { sec_sev = ghes_severity(gdata->error_severity); - if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, + sec_type = *(uuid_le *)gdata->section_type; + + if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) + fru_id = (uuid_le *)gdata->fru_id; + if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) + fru_text = gdata->fru_text; + + if (!uuid_le_cmp(sec_type, CPER_SEC_PLATFORM_MEM)) { struct cper_sec_mem_err *mem_err; @@ -473,7 +485,7 @@ static void ghes_do_proc(struct ghes *ghes, ghes_handle_memory_failure(gdata, sev); } #ifdef CONFIG_ACPI_APEI_PCIEAER - else if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, + else if (!uuid_le_cmp(sec_type, CPER_SEC_PCIE)) { struct cper_sec_pcie *pcie_err; @@ -506,6 +518,12 @@ static void ghes_do_proc(struct ghes *ghes, } #endif + else { + void *unknown_err = acpi_hest_generic_data_payload(gdata); + trace_unknown_sec_event(&sec_type, + fru_id, fru_text, sec_sev, + unknown_err, gdata->error_data_length); + } } } diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c index b67dd36..fb2500b 100644 --- a/drivers/ras/ras.c +++ b/drivers/ras/ras.c @@ -27,3 +27,4 @@ subsys_initcall(ras_init); EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event); #endif EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event); +EXPORT_TRACEPOINT_SYMBOL_GPL(unknown_sec_event); diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h index 1791a12..5861b6f 100644 --- a/include/ras/ras_event.h +++ b/include/ras/ras_event.h @@ -162,6 +162,51 @@ TRACE_EVENT(mc_event, ); /* + * Unknown Section Report + * + * This event is generated when hardware detected a hardware + * error event, which may be of non-standard section as defined + * in UEFI spec appendix "Common Platform Error Record", or may + * be of sections for which TRACE_EVENT is not defined. + * + */ +TRACE_EVENT(unknown_sec_event, + + TP_PROTO(const uuid_le *sec_type, +const uuid_le *fru_id, +const char *fru_text, +const u8 sev, +const u8 *err, +const u32 len), + + TP_ARGS(sec_type, fru_id, fru_text, sev, err, len), + + TP_STRUCT__entry( + __array(char, sec_type, 16) + __array(char, fru_id, 16) + __string(fru_text, fru_text) + __field(u8, sev) + __field(u32, len) + __dynamic_array(u8, buf, len) + ), + + TP_fast_assign( + memcpy(__entry->sec_type, sec_type, sizeof(uuid_le)); + memcpy(__entry->fru_id, fru_id, sizeof(uuid_le)); + __assign_str(fru_text, fru_text); + __entry->sev = sev; + __entry->len = len; + memcpy(__get_dynamic_array(buf), err, len); + ), + + TP_printk("severity: %d; sec type:%pU; FRU: %pU %s; data len:%d; raw data:%s", + __entry->sev, __entry->sec_type, + __entry->fru_id, __get_str(fru_text), + __entry->len, + __print_hex(__get_dynamic_array(buf), __entry->len)) +
[PATCH V7 07/10] efi: print unrecognized CPER section
UEFI spec allows for non-standard section in Common Platform Error Record. This is defined in section N.2.3 of UEFI version 2.5. Currently if the CPER section's type (UUID) does not match with one of the section types that the kernel knows how to parse, the section is skipped. Therefore, user is not able to see such CPER data, for instance, error record of non-standard section. For above mentioned case, this change prints out the raw data in hex in dmesg buffer. Data length is taken from Error Data length field of Generic Error Data Entry. Following is a sample output from dmesg: [ 115.771702] {1}[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2 [ 115.779042] {1}[Hardware Error]: It has been corrected by h/w and requires no further action [ 115.787456] {1}[Hardware Error]: event severity: corrected [ 115.792927] {1}[Hardware Error]: Error 0, type: corrected [ 115.798415] {1}[Hardware Error]: fru_id: ---- [ 115.805596] {1}[Hardware Error]: fru_text: [ 115.816105] {1}[Hardware Error]: section type: d2e2621c-f936-468d-0d84-15a4ed015c8b [ 115.823880] {1}[Hardware Error]: section length: 88 [ 115.828779] {1}[Hardware Error]: : 0101 0002 5f434345 525f4543 [ 115.836153] {1}[Hardware Error]: 0010: 574d [ 115.843531] {1}[Hardware Error]: 0020: [ 115.850908] {1}[Hardware Error]: 0030: [ 115.858288] {1}[Hardware Error]: 0040: fe80 0004 5f434345 [ 115.865665] {1}[Hardware Error]: 0050: 525f4543 574d Signed-off-by: Tyler Baicar Signed-off-by: Jonathan (Zhixiong) Zhang --- drivers/firmware/efi/cper.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c index c2b0a12..48cb8ee 100644 --- a/drivers/firmware/efi/cper.c +++ b/drivers/firmware/efi/cper.c @@ -591,8 +591,16 @@ static void cper_estatus_print_section( cper_print_proc_arm(newpfx, arm_err); else goto err_section_too_small; - } else - printk("%s""section type: unknown, %pUl\n", newpfx, sec_type); + } else { + const void *unknown_err; + + unknown_err = acpi_hest_generic_data_payload(gdata); + printk("%ssection type: %pUl\n", newpfx, sec_type); + printk("%ssection length: %d\n", newpfx, + gdata->error_data_length); + print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, + unknown_err, gdata->error_data_length, 0); + } return; -- Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH] ASoC: sunxi: Add bindings for sun8i to SPDIF
On Thu, Jan 12, 2017 at 06:33:43PM +0100, codekip...@gmail.com wrote: > From: Marcus Cooper > > The H3 SoC uses the same SPDIF block as found in earlier SoCs, but the > transmit fifo is at a different address. > > Signed-off-by: Marcus Cooper Acked-by: Maxime Ripard -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks
On Thu, Jan 12, 2017 at 11:58:09AM -0500, Nayna Jain wrote: > This patch implements the TPM 2.0 capability TPM_CAP_PCRS to > retrieve the active PCR banks from the TPM. This is needed > to enable extending all active banks as recommended by TPM 2.0 > TCG Specification. > > Signed-off-by: Nayna Jain > --- > drivers/char/tpm/tpm.h | 4 +++ > drivers/char/tpm/tpm2-cmd.c | 59 > + > 2 files changed, 63 insertions(+) > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h > index 1ae9768..573 100644 > --- a/drivers/char/tpm/tpm.h > +++ b/drivers/char/tpm/tpm.h > @@ -127,6 +127,7 @@ enum tpm2_permanent_handles { > }; > > enum tpm2_capabilities { > + TPM2_CAP_PCRS = 5, > TPM2_CAP_TPM_PROPERTIES = 6, > }; > > @@ -187,6 +188,8 @@ struct tpm_chip { > > const struct attribute_group *groups[3]; > unsigned int groups_cnt; > + > + u16 active_banks[7]; > #ifdef CONFIG_ACPI > acpi_handle acpi_dev_handle; > char ppi_version[TPM_PPI_VERSION_LEN + 1]; > @@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip); > void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type); > unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); > int tpm2_probe(struct tpm_chip *chip); > +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip); > #endif > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c > index 6eda239..87388921 100644 > --- a/drivers/char/tpm/tpm2-cmd.c > +++ b/drivers/char/tpm/tpm2-cmd.c > @@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out { > __be32 value; > } __packed; > > +struct tpm2_tpms_pcr_selection { > + __be16 hash_alg; > + u8 size_of_select; > + u8 pcr_select[3]; > +} __packed; Please move this right before tpm2_get_pcr_allocation. Drop 'tpms_'. > + > struct tpm2_get_random_in { > __be16 size; > } __packed; > @@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip) > } > } > > + rc = tpm2_get_pcr_allocation(chip); > + Please have this call in the commit where you actually use it Does not make any sense here > out: > if (rc > 0) > rc = -ENODEV; > return rc; > } > + > +/** > + * tpm2_get_pcr_allocation() - get TPM active PCR banks. > + * > + * @chip: TPM chip to use. > + * > + * Return: Same as with tpm_transmit_cmd. > + */ > +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip) > +{ > + struct tpm2_tpms_pcr_selection pcr_selection; > + struct tpm_buf buf; > + void *marker; > + unsigned int count = 0; > + int rc; > + int i; > + > + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY); > + if (rc) > + return rc; > + > + tpm_buf_append_u32(&buf, TPM2_CAP_PCRS); > + tpm_buf_append_u32(&buf, 0); > + tpm_buf_append_u32(&buf, 1); > + > + rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0, > + "get tpm pcr allocation"); > + if (rc < 0) > + goto out; > + > + count = be32_to_cpup( > + (__be32 *) &buf.data[TPM_HEADER_SIZE + 5]); Please do not add a space after cast. This has been an issue in your previous patches too so try to do it right next time. > + > + if (count > ARRAY_SIZE(chip->active_banks)) > + return -ENODEV; > + > + marker = &buf.data[TPM_HEADER_SIZE + 9]; > + for (i = 0; i < count; i++) { > + memcpy(&pcr_selection, marker, sizeof(pcr_selection)); > + chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg); > + marker = marker + sizeof(struct tpm2_tpms_pcr_selection); > + } > + > +out: > + if (count < ARRAY_SIZE(chip->active_banks)) > + chip->active_banks[count] = 0; > + > + tpm_buf_destroy(&buf); > + > + return rc; > +} > -- > 2.5.0 > /Jarkko
Re: sysfs deferred_probe attribute
On Thu, 2017-01-12 at 18:41 +0100, Greg Kroah-Hartman wrote: > On Thu, Jan 12, 2017 at 11:27:01AM -0600, Rob Herring wrote: > > I just noticed that we have a new device attribute 'deferred_probe' > > added in 4.10 with this commit: > > > > commit 6751667a29d6fd64afb9ce30567ad616b68ed789 > > Author: Ben Hutchings > > Date: Tue Aug 16 14:34:18 2016 +0100 > > > > driver core: Add deferred_probe attribute to devices in sysfs > > > > It is sometimes useful to know that a device is on the deferred probe > > list rather than, say, not having a driver available. Expose this > > information to user-space. > > > > Signed-off-by: Ben Hutchings > > Signed-off-by: Greg Kroah-Hartman > > > > > > It seems like a bad idea to add an ABI for an internal kernel feature. > > When/if we replace deferred probe with something better based on > > functional dependencies are we going to keep this attr around? Or > > remove it and assume no userspace uses it? It should be removed then (and replaced with some kind of representation of dependencies). > > Perhaps it should be hidden > > behind CONFIG_DEBUG or just make a debugfs file that lists the > > deferred list. Then you wouldn't have to hunt for what got deferred. > > Ah, debugfs would be nice, I'd much prefer that. I don't know how Ben > is using this, but I think that would make more sense to me. I'm not using it any programmatic way, and don't intend to. debugfs would be OK, but attaching it to devices was easy to do and seemed to make sense. Ben. -- Ben Hutchings Software Developer, Codethink Ltd.
Re: [PATCH v5] DAX: enable iostat for read/write
On Thu, 2017-01-12 at 10:02 -0800, Joe Perches wrote: > On Thu, 2017-01-12 at 11:38 -0700, Toshi Kani wrote: > > DAX IO path does not support iostat, but its metadata IO path does. > > Therefore, iostat shows metadata IO statistics only, which has been > > confusing to users. > > [] > > diff --git a/fs/dax.c b/fs/dax.c > > [] > > @@ -1058,12 +1058,24 @@ dax_iomap_rw(struct kiocb *iocb, struct > > iov_iter *iter, > > { > > struct address_space *mapping = iocb->ki_filp->f_mapping; > > struct inode *inode = mapping->host; > > + struct gendisk *disk = inode->i_sb->s_bdev->bd_disk; > > loff_t pos = iocb->ki_pos, ret = 0, done = 0; > > unsigned flags = 0; > > + unsigned long start = 0; > > + int do_acct = blk_queue_io_stat(disk->queue); > > > > if (iov_iter_rw(iter) == WRITE) > > flags |= IOMAP_WRITE; > > > > + if (do_acct) { > > + sector_t sec = iov_iter_count(iter) >> 9; > > + > > + start = jiffies; > > + generic_start_io_acct(iov_iter_rw(iter), > > + min_t(unsigned long, 1, > > sec), > > I believe I mislead you with a thinko. > > Your original code was > (!sec) ? 1 : sec > and I suggested incorrectly using min_t > > It should of course be max_t. Sorry. My bad. I should have caught it. > Also, as sec is now sector_t (u64), perhaps this > unsigned long cast is incorrect. I see. Since iov_iter_count() returns a size_t value, I will use 'size_t' for 'sec' as you originally suggested. Thanks, -Toshi
Re: [PATCH 01/18] Drivers: hv: vmbus: Move the definition of hv_x64_msr_hypercall_contents
On Thu, 12 Jan 2017 02:32:24 + KY Srinivasan wrote: > > -Original Message- > > From: Greg KH [mailto:gre...@linuxfoundation.org] > > Sent: Tuesday, January 10, 2017 9:27 AM > > To: KY Srinivasan > > Cc: linux-kernel@vger.kernel.org; de...@linuxdriverproject.org; > > o...@aepfle.de; a...@canonical.com; vkuzn...@redhat.com; > > jasow...@redhat.com; leann.ogasaw...@canonical.com; > > rka...@virtuozzo.com; x...@kernel.org; t...@linutronix.de; h...@zytor.com > > Subject: Re: [PATCH 01/18] Drivers: hv: vmbus: Move the definition of > > hv_x64_msr_hypercall_contents > > > > On Fri, Dec 30, 2016 at 01:35:55PM -0800, k...@exchange.microsoft.com > > wrote: > > > From: K. Y. Srinivasan > > > > > > As part of the effort to separate out architecture specific code, move the > > > definition of hv_x64_msr_hypercall_contents to x86 specific header file. > > > > > > Signed-off-by: K. Y. Srinivasan > > > --- > > > arch/x86/include/asm/mshyperv.h | 12 > > > drivers/hv/hyperv_vmbus.h | 15 --- > > > 2 files changed, 12 insertions(+), 15 deletions(-) > > > > This series doesn't apply against my tree. Can you please refresh it > > and resend? > > Will do. > > K. Y Send me the patches, I have a vmbus-next tree ready for pull request.
[PATCH v2 1/2] of: base: add support to find the level of the last cache
It is useful to have helper function just to get the number of cache levels for a given logical cpu. We can obtain the same by just checking the level at which the last cache is present. This patch adds support to find the level of the last cache for a given cpu. It will be used on ARM64 platform where the device tree provides the information for the additional non-architected/transparent/external last level caches that are not integrated with the processors. Suggested-by: Rob Herring Cc: Rob Herring Cc: Mark Rutland Signed-off-by: Sudeep Holla --- drivers/of/base.c | 27 +++ include/linux/of.h | 1 + 2 files changed, 28 insertions(+) v1->v2: - Moved to using "cache-level" in the last level cache instead of counting through all the nodes as suggested by Rob diff --git a/drivers/of/base.c b/drivers/of/base.c index d4bea3c797d6..c1128a077aea 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -2268,6 +2269,32 @@ struct device_node *of_find_next_cache_node(const struct device_node *np) } /** + * of_find_last_cache_level - Find the level at which the last cache is + * present for the given logical cpu + * + * @cpu: cpu number(logical index) for which the last cache level is needed + * + * Returns the the level at which the last cache is present. It is exactly + * same as the total number of cache levels for the given logical cpu. + */ +int of_find_last_cache_level(unsigned int cpu) +{ + int cache_level = 0; + struct device_node *prev = NULL, *np = of_cpu_device_node_get(cpu); + + while (np) { + prev = np; + of_node_put(np); + np = of_find_next_cache_node(np); + } + + if (prev) + of_property_read_u32(prev, "cache-level", &cache_level); + + return cache_level; +} + +/** * of_graph_parse_endpoint() - parse common endpoint node properties * @node: pointer to endpoint device_node * @endpoint: pointer to the OF endpoint data structure diff --git a/include/linux/of.h b/include/linux/of.h index d72f01009297..21e6323de0f3 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -280,6 +280,7 @@ extern struct device_node *of_get_child_by_name(const struct device_node *node, /* cache lookup */ extern struct device_node *of_find_next_cache_node(const struct device_node *); +extern int of_find_last_cache_level(unsigned int cpu); extern struct device_node *of_find_node_with_property( struct device_node *from, const char *prop_name); -- 2.7.4
Re: [PATCH] Input: egalax_ts - do not release gpio if probe successful
Hi Gary, On Wed, Jan 11, 2017 at 06:28:41PM +0100, Gary Bisson wrote: > Thus preventing anyone to later modify the interrupt GPIO direction > and/or state without the driver knowing. I am afraid not releasing gpio after waking up the controller will cause request_irq to fail if we are using the same pin for interrupt and wakeup (as majority of current DTSes do: see arch/arm/boot/dts/imx53-tx53-x13x.dts for example). You'll need to figure out if irq is backed by the same gpio as wakeup and act accordingly. What setup did you test this on? Was it shared pin or dedicated wakeup? Thanks. > > Also checking if device is present before allocating the input device. > > Signed-off-by: Gary Bisson > --- > drivers/input/touchscreen/egalax_ts.c | 56 > --- > 1 file changed, 25 insertions(+), 31 deletions(-) > > diff --git a/drivers/input/touchscreen/egalax_ts.c > b/drivers/input/touchscreen/egalax_ts.c > index 1afc08b08155..f6b94bb19bd8 100644 > --- a/drivers/input/touchscreen/egalax_ts.c > +++ b/drivers/input/touchscreen/egalax_ts.c > @@ -62,6 +62,7 @@ > struct egalax_ts { > struct i2c_client *client; > struct input_dev*input_dev; > + struct gpio_desc*wakeup_gpio; > }; > > static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) > @@ -120,36 +121,21 @@ static irqreturn_t egalax_ts_interrupt(int irq, void > *dev_id) > } > > /* wake up controller by an falling edge of interrupt gpio. */ > -static int egalax_wake_up_device(struct i2c_client *client) > +static int egalax_wake_up_device(struct gpio_desc *wakeup_gpio) > { > - struct device_node *np = client->dev.of_node; > - int gpio; > int ret; > > - if (!np) > - return -ENODEV; > - > - gpio = of_get_named_gpio(np, "wakeup-gpios", 0); > - if (!gpio_is_valid(gpio)) > - return -ENODEV; > - > - ret = gpio_request(gpio, "egalax_irq"); > - if (ret < 0) { > - dev_err(&client->dev, > - "request gpio failed, cannot wake up controller: %d\n", > - ret); > + /* wake up controller via an falling edge on IRQ gpio. */ > + ret = gpiod_direction_output(wakeup_gpio, 0); > + if (ret < 0) > return ret; > - } > > - /* wake up controller via an falling edge on IRQ gpio. */ > - gpio_direction_output(gpio, 0); > - gpio_set_value(gpio, 1); > + gpiod_set_value(wakeup_gpio, 1); > > /* controller should be waken up, return irq. */ > - gpio_direction_input(gpio); > - gpio_free(gpio); > + ret = gpiod_direction_input(wakeup_gpio); > > - return 0; > + return ret; > } > > static int egalax_firmware_version(struct i2c_client *client) > @@ -177,17 +163,15 @@ static int egalax_ts_probe(struct i2c_client *client, > return -ENOMEM; > } > > - input_dev = devm_input_allocate_device(&client->dev); > - if (!input_dev) { > - dev_err(&client->dev, "Failed to allocate memory\n"); > - return -ENOMEM; > + ts->wakeup_gpio = devm_gpiod_get_index(&client->dev, "wakeup", > +0, GPIOD_ASIS); > + if (IS_ERR(ts->wakeup_gpio)) { > + dev_err(&client->dev, "Failed to get wakeup gpio"); > + return -ENODEV; > } > > - ts->client = client; > - ts->input_dev = input_dev; > - > /* controller may be in sleep, wake it up. */ > - error = egalax_wake_up_device(client); > + error = egalax_wake_up_device(ts->wakeup_gpio); > if (error) { > dev_err(&client->dev, "Failed to wake up the controller\n"); > return error; > @@ -199,6 +183,15 @@ static int egalax_ts_probe(struct i2c_client *client, > return error; > } > > + input_dev = devm_input_allocate_device(&client->dev); > + if (!input_dev) { > + dev_err(&client->dev, "Failed to allocate memory\n"); > + return -ENOMEM; > + } > + > + ts->client = client; > + ts->input_dev = input_dev; > + > input_dev->name = "EETI eGalax Touch Screen"; > input_dev->id.bustype = BUS_I2C; > > @@ -254,8 +247,9 @@ static int __maybe_unused egalax_ts_suspend(struct device > *dev) > static int __maybe_unused egalax_ts_resume(struct device *dev) > { > struct i2c_client *client = to_i2c_client(dev); > + struct egalax_ts *ts = i2c_get_clientdata(client); > > - return egalax_wake_up_device(client); > + return egalax_wake_up_device(ts->wakeup_gpio); > } > > static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, > egalax_ts_resume); > -- > 2.11.0 > -- Dmitry
Re: [PATCH net-next 1/4] siphash: add cryptographically secure PRF
On Thu, Jan 12, 2017 at 4:04 PM, Herbert Xu wrote: >> typedef struct { >>u64 v[2]; >> } siphash_key_t; > > If it's just an 128-bit value then we have u128 in crypto/b128ops.h > that could be generalised for this. Nope, it's actually two 64-bit values. Yes, the user fills it in as one blob to get_random_bytes, but it's used internally by the algorithm as two distinct variables (which conveniently fit into 64-bit registers).
[PATCH RFC] sched/fair: unthrottle cfs_rq in FIFO order and only once per period
I'm seeing live-locks on 32-core machine with 32 busy-loops running inside cpu cgroup with limit set equal to 0.33 core (cpu.cfs_quota_us = 33000, cpu.cfs_period_us = 10) : some threads almost never runs. This is very nasty behavior: sometimes throttled tasks also hold kernel locks, for example mmap_sem and block proc files for system-wide "ps ax". This happens because throttle_cfs_rq() inserts cfs-rq into head and unthrottle in distribute_cfs_runtime() starts from head too. Cfs_rqs at the end might never get runtime if limits is set low enough. Originally untrottle worked in FIFO order but commit c06f04c70489 ("sched: Fix potential near-infinite distribute_cfs_runtime() loop") switched to LIFO because distribute_cfs_runtime() could unthrottle the same cfq-rq endlessly. This was happened because loop around distribute_cfs_runtime() in function do_sched_cfs_period_timer() and because cfs_b->runtime here set to zero to prevent acquiring runtime from global pool while this loop works. That zeroing was removed by commit mentioned above. This one removes loop. This patch reverts unthrottling back to FIFO order and checks expiration time during distribution: if cfs_rq already was unthrottled during this period then its expiration is equal to currently distributed. Then we'll skip it for now and will try to unthottle at next period. Signed-off-by: Konstantin Khlebnikov Fixes: c06f04c70489 ("sched: Fix potential near-infinite distribute_cfs_runtime() loop") Cc: Ben Segall Cc: Ingo Molnar Cc: Peter Zijlstra --- kernel/sched/fair.c | 38 +- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6559d197e08a..b30412e3d7c2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4162,10 +4162,9 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) empty = list_empty(&cfs_b->throttled_cfs_rq); /* -* Add to the _head_ of the list, so that an already-started -* distribute_cfs_runtime will not see us +* Add to the _tail_ of the list, untrottle happens in FIFO order */ - list_add_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); + list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); /* * If we're the first throttled task, make sure the bandwidth @@ -4240,6 +4239,15 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b, if (!cfs_rq_throttled(cfs_rq)) goto next; + /* +* Give throttled cfs_rq 1 ns of runtime. It will take more +* from global pool when needed. But skip cfs_rq if expiration +* time equals to ours, this means we already untrottled it in +* this loop and global pool is already depleted. +*/ + if (cfs_rq->runtime_expires == expires) + goto next; + runtime = -cfs_rq->runtime_remaining + 1; if (runtime > remaining) runtime = remaining; @@ -4302,24 +4310,20 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun) runtime_expires = cfs_b->runtime_expires; /* -* This check is repeated as we are holding onto the new bandwidth while -* we unthrottle. This can potentially race with an unthrottled group -* trying to acquire new bandwidth from the global pool. This can result -* in us over-using our runtime if it is all used during this loop, but -* only by limited amounts in that extreme case. +* This can potentially race with an unthrottled group trying to +* acquire new bandwidth from the global pool. This can result +* in us over-using our runtime if it is all used during this loop, +* but only by limited amounts in that extreme case. */ - while (throttled && cfs_b->runtime > 0) { - runtime = cfs_b->runtime; - raw_spin_unlock(&cfs_b->lock); - /* we can't nest cfs_b->lock while distributing bandwidth */ - runtime = distribute_cfs_runtime(cfs_b, runtime, -runtime_expires); - raw_spin_lock(&cfs_b->lock); + runtime = cfs_b->runtime; - throttled = !list_empty(&cfs_b->throttled_cfs_rq); + /* we can't nest cfs_b->lock while distributing bandwidth */ + raw_spin_unlock(&cfs_b->lock); + runtime = distribute_cfs_runtime(cfs_b, runtime, runtime_expires); + raw_spin_lock(&cfs_b->lock); + if (runtime_expires == cfs_b->runtime_expires) cfs_b->runtime -= min(runtime, cfs_b->runtime); - } /* * While we are ensured activity in the period following an
[PATCH v2 2/2] arm64: cacheinfo: add support to override cache levels via device tree
The cache hierarchy can be identified through Cache Level ID(CLIDR) architected system register. However in some cases it will provide only the number of cache levels that are integrated into the processor itself. In other words, it can't provide any information about the caches that are external and/or transparent. Some platforms require to export the information about all such external caches to the userspace applications via the sysfs interface. This patch adds support to override the cache levels using device tree to take such external non-architected caches into account. Cc: Catalin Marinas Cc: Will Deacon Cc: Mark Rutland Signed-off-by: Sudeep Holla --- arch/arm64/kernel/cacheinfo.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c index 9617301f76b5..3f2250fc391b 100644 --- a/arch/arm64/kernel/cacheinfo.c +++ b/arch/arm64/kernel/cacheinfo.c @@ -84,7 +84,7 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, static int __init_cache_level(unsigned int cpu) { - unsigned int ctype, level, leaves; + unsigned int ctype, level, leaves, of_level; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { @@ -97,6 +97,17 @@ static int __init_cache_level(unsigned int cpu) leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; } + of_level = of_find_last_cache_level(cpu); + if (level < of_level) { + /* +* some external caches not specified in CLIDR_EL1 +* the information may be available in the device tree +* only unified external caches are considered here +*/ + leaves += (of_level - level); + level = of_level; + } + this_cpu_ci->num_levels = level; this_cpu_ci->num_leaves = leaves; return 0; -- 2.7.4
Re: [PATCH] livepatch/module: print notice of TAINT_LIVEPATCH
On Thu, Jan 12, 2017 at 11:57:44AM -0500, Joe Lawrence wrote: > Add back the "tainting kernel with TAINT_LIVEPATCH" kernel log message > that commit 2992ef29ae01 ("livepatch/module: make TAINT_LIVEPATCH > module-specific") dropped. Now that it's a module-specific taint flag, > include the module name. > > Signed-off-by: Joe Lawrence Acked-by: Josh Poimboeuf > --- > kernel/module.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/kernel/module.c b/kernel/module.c > index 5088784c0cf9..330f64e7e193 100644 > --- a/kernel/module.c > +++ b/kernel/module.c > @@ -2812,6 +2812,8 @@ static int check_modinfo_livepatch(struct module *mod, > struct load_info *info) > if (get_modinfo(info, "livepatch")) { > mod->klp = true; > add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK); > + pr_notice_once("%s: tainting kernel with TAINT_LIVEPATCH\n", > +mod->name); > } > > return 0; > -- > 1.8.3.1 > > -- > To unsubscribe from this list: send the line "unsubscribe live-patching" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Josh
Re: [PATCH] partially revert "xen: Remove event channel notification through Xen PCI platform device"
On 01/11/2017 06:36 PM, Stefano Stabellini wrote: > The following commit: > > commit 72a9b186292d98494f26cfd24a1621796209 > Author: KarimAllah Ahmed > Date: Fri Aug 26 23:55:36 2016 +0200 > > xen: Remove event channel notification through Xen PCI platform device > > broke Linux when booting as Dom0 on Xen in a nested Xen environment (Xen > installed inside a Xen VM). In this scenario, Linux is a PV guest, but > at the same time it uses the platform-pci driver to receive > notifications from L0 Xen. vector callbacks are not available because L1 > Xen doesn't allow them. (+Konrad who has been running nested) > > Partially revert the offending commit, by restoring IRQ based > notifications for PV guests only. I restored only the code which is > strictly needed and replaced the xen_have_vector_callback checks within > it with xen_pv_domain() checks. > > Signed-off-by: Stefano Stabellini > > --- > Alternatively, I could also restore the xen_have_vector_callback > checks. In general, it's best to have feature flag checks than umbrella > xen_pv/hvm_domain() checks. I don't think it's worth doing given that we know that HVM we cant' run without this feature (we have BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector)) in xen_hvm_guest_init()). > --- > > diff --git a/drivers/xen/platform-pci.c b/drivers/xen/platform-pci.c > index b59c9455..1477f1d 100644 > --- a/drivers/xen/platform-pci.c > +++ b/drivers/xen/platform-pci.c > @@ -42,6 +42,7 @@ > static unsigned long platform_mmio; > static unsigned long platform_mmio_alloc; > static unsigned long platform_mmiolen; > +static uint64_t callback_via; > > static unsigned long alloc_xen_mmio(unsigned long len) > { > @@ -54,6 +55,51 @@ static unsigned long alloc_xen_mmio(unsigned long len) > return addr; > } > > +static uint64_t get_callback_via(struct pci_dev *pdev) > +{ > + u8 pin; > + int irq; > + > + irq = pdev->irq; > + if (irq < 16) > + return irq; /* ISA IRQ */ > + > + pin = pdev->pin; > + > + /* We don't know the GSI. Specify the PCI INTx line instead. */ > + return ((uint64_t)0x01 << 56) | /* PCI INTx identifier */ You can use HVM_CALLBACK_VIA_TYPE_SHIFT here. -boris > + ((uint64_t)pci_domain_nr(pdev->bus) << 32) | > + ((uint64_t)pdev->bus->number << 16) | > + ((uint64_t)(pdev->devfn & 0xff) << 8) | > + ((uint64_t)(pin - 1) & 3); > +} > + >
Re: Nokia N900: mixers changed between 4.6 and 4.10, no longer can use in-call speaker
On Thursday 12 January 2017 19:18:26 Pavel Machek wrote: > Hi! > > In v4.10 (and probably v4.9, too) I can no longer use the in-call > speaker. I can no longer use the wired headset, either. > > v4.4 (and probably v4.6) works ok. > > Any ideas? Does wired headset / in-call speaker work for you? > > "Mono" and "Mono DAC" options are still there.. but something else > changed, as alsamixer now shows way many more options (meaning they > are shorter?) and I get complains from alsactl: > > alsactl: set_control:1328: failed to obtain info for control #49 (No > such file or directory) > ... > alsactl: set_control:1328: failed to obtain info for control #229 (No > such file or directory) > > > > Pavel Looks like there are not so much commits related to sound/soc/omap/rx51.c Maybe it can be one of these twos? cb7e62256e99d285e415cf75db67558f0f8bb107 6d2de5ab4328718302c54b20222c6b1a574c3fce -- Pali Rohár pali.ro...@gmail.com signature.asc Description: This is a digitally signed message part.
[PATCH v3 0/2] reset: Make optional functions really optional.
v3: - Improve description of changes ocurring in the patchset - Add 2 new return errors. v2: - Make some comments more explicit - Add optional flag to reduce code duplication - Change shared flag from int to bool to match optional flag Up until now optional functions in the reset API were similar to the non optional. This patch corrects that, while maintaining compatibility with existing drivers. As suggested here: https://lkml.org/lkml/2016/12/14/502 Ramiro Oliveira (2): reset: Change shared flag from int to bool reset: make optional functions really optional drivers/reset/core.c | 63 +++ include/linux/reset.h | 45 2 files changed, 75 insertions(+), 33 deletions(-) -- 2.11.0
[PATCH v3 1/2] reset: Change shared flag from int to bool
Since the new parameter being added is going to be a bool this patch changes the shared flag from int to bool to match the new parameter. Signed-off-by: Ramiro Oliveira --- drivers/reset/core.c | 8 include/linux/reset.h | 32 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 10368ed8fd13..272c1e4ecb5c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -41,7 +41,7 @@ struct reset_control { struct list_head list; unsigned int id; unsigned int refcnt; - int shared; + bool shared; atomic_t deassert_count; atomic_t triggered_count; }; @@ -254,7 +254,7 @@ EXPORT_SYMBOL_GPL(reset_control_status); static struct reset_control *__reset_control_get( struct reset_controller_dev *rcdev, - unsigned int index, int shared) + unsigned int index, bool shared) { struct reset_control *rstc; @@ -299,7 +299,7 @@ static void __reset_control_put(struct reset_control *rstc) } struct reset_control *__of_reset_control_get(struct device_node *node, -const char *id, int index, int shared) +const char *id, int index, bool shared) { struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; @@ -379,7 +379,7 @@ static void devm_reset_control_release(struct device *dev, void *res) } struct reset_control *__devm_reset_control_get(struct device *dev, -const char *id, int index, int shared) +const char *id, int index, bool shared) { struct reset_control **ptr, *rstc; diff --git a/include/linux/reset.h b/include/linux/reset.h index 5daff15722d3..ec1d1fd28f5f 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -13,10 +13,10 @@ int reset_control_deassert(struct reset_control *rstc); int reset_control_status(struct reset_control *rstc); struct reset_control *__of_reset_control_get(struct device_node *node, -const char *id, int index, int shared); +const char *id, int index, bool shared); void reset_control_put(struct reset_control *rstc); struct reset_control *__devm_reset_control_get(struct device *dev, -const char *id, int index, int shared); +const char *id, int index, bool shared); int __must_check device_reset(struct device *dev); @@ -69,14 +69,14 @@ static inline int device_reset_optional(struct device *dev) static inline struct reset_control *__of_reset_control_get( struct device_node *node, - const char *id, int index, int shared) + const char *id, int index, bool shared) { return ERR_PTR(-ENOTSUPP); } static inline struct reset_control *__devm_reset_control_get( struct device *dev, - const char *id, int index, int shared) + const char *id, int index, bool shared) { return ERR_PTR(-ENOTSUPP); } @@ -132,19 +132,19 @@ __must_check reset_control_get_exclusive(struct device *dev, const char *id) static inline struct reset_control *reset_control_get_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); } static inline struct reset_control *reset_control_get_optional_exclusive( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 0); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, false); } static inline struct reset_control *reset_control_get_optional_shared( struct device *dev, const char *id) { - return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, 1); + return __of_reset_control_get(dev ? dev->of_node : NULL, id, 0, true); } /** @@ -185,7 +185,7 @@ static inline struct reset_control *of_reset_control_get_exclusive( static inline struct reset_control *of_reset_control_get_shared( struct device_node *node, const char *id) { - return __of_reset_control_get(node, id, 0, 1); + return __of_reset_control_get(node, id, 0, true); } /** @@ -202,7 +202,7 @@ static inline struct reset_control *of_reset_control_get_shared( static inline struct reset_control *of_reset_control_get_exclusive_by_index(
[PATCH v3 2/2] reset: make optional functions really optional
"The *_get_optional_* functions weren't really optional so this patch makes them really optional. These *_get_optional_* functions will now return NULL instead of an error if no matching reset phandle is found in the DT, and all the reset_control_* functions now accept NULL rstc pointers. Signed-off-by: Ramiro Oliveira --- drivers/reset/core.c | 59 --- include/linux/reset.h | 45 ++- 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 272c1e4ecb5c..7b679b0bfef8 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -143,12 +143,18 @@ EXPORT_SYMBOL_GPL(devm_reset_controller_register); * a no-op. * Consumers must not use reset_control_(de)assert on shared reset lines when * reset_control_reset has been used. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_reset(struct reset_control *rstc) { int ret; - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->reset) @@ -182,10 +188,17 @@ EXPORT_SYMBOL_GPL(reset_control_reset); * internal state to be reset, but must be prepared for this to happen. * Consumers must not use reset_control_reset on shared reset lines when * reset_control_(de)assert has been used. + * return 0. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_assert(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->assert) @@ -213,10 +226,17 @@ EXPORT_SYMBOL_GPL(reset_control_assert); * After calling this function, the reset is guaranteed to be deasserted. * Consumers must not use reset_control_reset on shared reset lines when * reset_control_(de)assert has been used. + * return 0. + * + * If rstc is NULL it is an optional reset and the function will just + * return 0. */ int reset_control_deassert(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (!rstc->rcdev->ops->deassert) @@ -237,12 +257,15 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); /** * reset_control_status - returns a negative errno if not supported, a * positive value if the reset line is asserted, or zero if the reset - * line is not asserted. + * line is not asserted or if the desc is NULL (optional reset). * @rstc: reset controller */ int reset_control_status(struct reset_control *rstc) { - if (WARN_ON(IS_ERR_OR_NULL(rstc))) + if (!rstc) + return 0; + + if (WARN_ON(IS_ERR(rstc))) return -EINVAL; if (rstc->rcdev->ops->status) @@ -299,7 +322,8 @@ static void __reset_control_put(struct reset_control *rstc) } struct reset_control *__of_reset_control_get(struct device_node *node, -const char *id, int index, bool shared) +const char *id, int index, bool shared, +bool optional) { struct reset_control *rstc; struct reset_controller_dev *r, *rcdev; @@ -313,14 +337,24 @@ struct reset_control *__of_reset_control_get(struct device_node *node, if (id) { index = of_property_match_string(node, "reset-names", id); - if (index < 0) - return ERR_PTR(-ENOENT); + if (index < 0) { + if (optional) + return NULL; + else + return (index == -EILSEQ) ? + ERR_PTR(index) : ERR_PTR(-ENOENT); + } } ret = of_parse_phandle_with_args(node, "resets", "#reset-cells", index, &args); - if (ret) - return ERR_PTR(ret); + if (ret) { + if (optional) + return NULL; + else + return (index == -EINVAL) ? + ERR_PTR(index) : ERR_PTR(-ENOENT); + } mutex_lock(&reset_list_mutex); rcdev = NULL; @@ -379,7 +413,8 @@ static void devm_reset_control_release(struct device *dev, void *res) } struct reset_control *__devm_reset_control_get(struct device *dev, -const char *id, int index, bool shared) +const char *id, int index, bool shared, +bool
Re: master - btrfs lockdep splat
On Thu, Jan 12, 2017 at 07:12:12PM +0100, Mike Galbraith wrote: > Greetings, > > I wanted to do some -rt testing, but seems non-rt kernels aren't > lockdep clean with btrfs /, making -rt testing a bit premature. > > (hm, 28a235931 Btrfs: fix lockdep warning on deadlock against an inode's log > mutex) It's rather a false-positive lockdep warning than a real deadlock, and a patch[1] has been queued to fix it. [1]: https://patchwork.kernel.org/patch/9473431/ Thanks, -liubo > > [ 876.622587] = > [ 876.622588] [ INFO: possible recursive locking detected ] > [ 876.622589] 4.10.0-master #36 Tainted: GE > [ 876.622590] - > [ 876.622591] vi/3364 is trying to acquire lock: > [ 876.622592] (&ei->log_mutex){+.+...}, at: [] > btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622628] but task is already holding lock: > [ 876.622629] (&ei->log_mutex){+.+...}, at: [] > btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622641] other info that might help us debug this: > [ 876.622642] Possible unsafe locking scenario: > [ 876.622643]CPU0 > [ 876.622644] > [ 876.622644] lock(&ei->log_mutex); > [ 876.622648] lock(&ei->log_mutex); > [ 876.622649] *** DEADLOCK *** > [ 876.622650] May be due to missing lock nesting notation > [ 876.622651] 3 locks held by vi/3364: > [ 876.622651] #0: (&sb->s_type->i_mutex_key#11){+.+.+.}, at: > [] btrfs_sync_file+0x154/0x480 [btrfs] > [ 876.622664] #1: (sb_internal){.+.+..}, at: [] > start_transaction+0x2a7/0x540 [btrfs] > [ 876.622674] #2: (&ei->log_mutex){+.+...}, at: [] > btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622685] stack backtrace: > [ 876.622687] CPU: 3 PID: 3364 Comm: vi Tainted: GE > 4.10.0-master #36 > [ 876.622688] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS > rel-1.8.1-0-g4adadbd-20161202_174313-build11a 04/01/2014 > [ 876.622689] Call Trace: > [ 876.622698] dump_stack+0x85/0xc9 > [ 876.622704] __lock_acquire+0x9f9/0x1550 > [ 876.622715] ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs] > [ 876.622717] lock_acquire+0xbd/0x200 > [ 876.622726] ? btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622732] mutex_lock_nested+0x69/0x660 > [ 876.622741] ? btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622750] ? __btrfs_release_delayed_node+0x79/0x2d0 [btrfs] > [ 876.622759] ? btrfs_commit_inode_delayed_inode+0xeb/0x130 [btrfs] > [ 876.622767] btrfs_log_inode+0x13c/0xbd0 [btrfs] > [ 876.622771] ? __might_sleep+0x4a/0x90 > [ 876.622781] ? btrfs_i_callback+0x20/0x20 [btrfs] > [ 876.622791] ? free_extent_buffer+0x4b/0x90 [btrfs] > [ 876.622799] btrfs_log_inode+0x572/0xbd0 [btrfs] > [ 876.622808] btrfs_log_inode_parent+0x26a/0x9b0 [btrfs] > [ 876.622812] ? dget_parent+0x77/0x170 > [ 876.622821] btrfs_log_dentry_safe+0x62/0x80 [btrfs] > [ 876.622830] btrfs_sync_file+0x2eb/0x480 [btrfs] > [ 876.622834] vfs_fsync_range+0x3d/0xb0 > [ 876.622836] ? trace_hardirqs_on_caller+0xf9/0x1c0 > [ 876.622837] do_fsync+0x3d/0x70 > [ 876.622839] SyS_fsync+0x10/0x20 > [ 876.622840] entry_SYSCALL_64_fastpath+0x1f/0xc2 > [ 876.622842] RIP: 0033:0x7f7fbe3da290 > [ 876.622843] RSP: 002b:7ffe2778f0b8 EFLAGS: 0246 ORIG_RAX: > 004a > [ 876.622844] RAX: ffda RBX: 0003 RCX: > 7f7fbe3da290 > [ 876.622845] RDX: 103d RSI: 0143e5d0 RDI: > 0003 > [ 876.622846] RBP: 01285f10 R08: 0143e5d0 R09: > > [ 876.622847] R10: R11: 0246 R12: > > [ 876.622847] R13: 2000 R14: 0001 R15: > 012821a0 > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [tpmdd-devel] [PATCH RFC v2 3/5] tpm: infrastructure for TPM spaces
On Thu, 2017-01-12 at 19:46 +0200, Jarkko Sakkinen wrote: > @@ -435,17 +440,23 @@ ssize_t tpm_transmit(struct tpm_chip *chip, > const u8 *buf, size_t bufsiz, > goto out; > > out_recv: > - rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); > - if (rc < 0) > + len = chip->ops->recv(chip, (u8 *) buf, bufsiz); > + if (len < 0) { > dev_err(&chip->dev, > - "tpm_transmit: tpm_recv: error %zd\n", rc); > + "tpm_transmit: tpm_recv: error %d\n", rc); > + rc = len; > + goto out; > + } > + > + rc = tpm2_commit_space(chip, space, ordinal, buf, bufsiz); I think this should be rc = tpm2_commit_space(chip, space, ordinal, buf, len) because tpm2_commit_space wants to know the length of the response, not the length of the original command. James
Re: [PATCH] f2fs: make discard command directly
On 01/12, Christoph Hellwig wrote: > On Wed, Jan 11, 2017 at 04:48:48PM -0800, Jaegeuk Kim wrote: > > This can reduce the backporting efforts. > > NAK. For one that is not a valid excuse for anything, and second > your remove respecting the granularity. Okay, I'll try from backporting side without this. :) Thanks,
[PATCH] firmware: qcom: scm: add a video command for state setting
This scm call is used to change the video core state, more specifically it is used to suspend and resume the core. Signed-off-by: Stanimir Varbanov --- Removed crypto clock enabling, which is not needed. drivers/firmware/qcom_scm-32.c | 18 ++ drivers/firmware/qcom_scm-64.c | 16 drivers/firmware/qcom_scm.c| 6 ++ drivers/firmware/qcom_scm.h| 2 ++ include/linux/qcom_scm.h | 2 ++ 5 files changed, 44 insertions(+) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c6aeedbdcbb0..82c1d8d0d36b 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -560,3 +560,21 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) return ret ? : le32_to_cpu(out); } + +int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 spare) +{ + struct { + __le32 state; + __le32 spare; + } req; + __le32 scm_ret = 0; + int ret; + + req.state = cpu_to_le32(state); + req.spare = cpu_to_le32(spare); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_VIDEO_SET_STATE, + &req, sizeof(req), &scm_ret, sizeof(scm_ret)); + + return ret ? : le32_to_cpu(scm_ret); +} diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 4a0f5ead4fb5..68484ea2aa51 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -358,3 +358,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) return ret ? : res.a1; } + +int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 spare) +{ + struct qcom_scm_desc desc = {0}; + struct arm_smccc_res res; + int ret; + + desc.args[0] = state; + desc.args[1] = spare; + desc.arginfo = QCOM_SCM_ARGS(2); + + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_VIDEO_SET_STATE, + &desc, &res); + + return ret ? : res.a1; +} diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 893f953eaccf..95d13d8e8871 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -324,6 +324,12 @@ bool qcom_scm_is_available(void) } EXPORT_SYMBOL(qcom_scm_is_available); +int qcom_scm_video_set_state(u32 state, u32 spare) +{ + return __qcom_scm_video_set_state(__scm->dev, state, spare); +} +EXPORT_SYMBOL(qcom_scm_video_set_state); + static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 3584b00fe7e6..4830559b2639 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -15,6 +15,8 @@ #define QCOM_SCM_SVC_BOOT 0x1 #define QCOM_SCM_BOOT_ADDR 0x1 #define QCOM_SCM_BOOT_ADDR_MC 0x11 +#define QCOM_SCM_VIDEO_SET_STATE 0xa +extern int __qcom_scm_video_set_state(struct device *dev, u32 state, u32 spare); #define QCOM_SCM_FLAG_HLOS 0x01 #define QCOM_SCM_FLAG_COLDBOOT_MC 0x02 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index cc32ab852fbc..2ece81a6b078 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -46,4 +46,6 @@ extern void qcom_scm_cpu_power_down(u32 flags); extern u32 qcom_scm_get_version(void); +extern int qcom_scm_video_set_state(u32 state, u32 spare); + #endif -- 2.7.4
Re: [PATCH RFC v2 5/5] tpm2: expose resource manager via a device link /dev/tpms
On Thu, Jan 12, 2017 at 07:46:08PM +0200, Jarkko Sakkinen wrote: > struct tpm_chip { > - struct device dev; > - struct cdev cdev; > + struct device dev, devrm; Hum.. devrm adds a new kref but doesn't do anything with the release function, so that is going to use after free, ie here: > put_device(&chip->dev); >+ put_device(&chip->devrm); > return ERR_PTR(rc); And other places. One solution is to get_device(chip->dev) after device_initialize(dev->rm) and add a devrm->dev.release function to do put_device(chip->dev) Jason
Re: [PATCH] arm64: errata: Provide macro for major and minor cpu revisions
On 12.01.17 15:33:15, Will Deacon wrote: > On Wed, Jan 11, 2017 at 01:11:42PM +0100, Robert Richter wrote: > > Definition of cpu ranges are hard to read if the cpu variant is not > > zero. Provide MIDR_CPU_FULL_REV() macro to describe the full hardware > > revision of a cpu including variant and (minor) revision. > > > > Signed-off-by: Robert Richter > > --- > > arch/arm64/include/asm/cputype.h | 3 +++ > > arch/arm64/kernel/cpu_errata.c | 15 +-- > > arch/arm64/kernel/cpufeature.c | 8 +++- > > 3 files changed, 15 insertions(+), 11 deletions(-) > > > > diff --git a/arch/arm64/include/asm/cputype.h > > b/arch/arm64/include/asm/cputype.h > > index 26a68ddb11c1..983e59cbdd54 100644 > > --- a/arch/arm64/include/asm/cputype.h > > +++ b/arch/arm64/include/asm/cputype.h > > @@ -56,6 +56,9 @@ > > (0xf<< MIDR_ARCHITECTURE_SHIFT) | \ > > ((partnum) << MIDR_PARTNUM_SHIFT)) > > > > +#define MIDR_CPU_FULL_REV(var, rev) \ > > + (((var) << MIDR_VARIANT_SHIFT) | (rev)) > > Minor nit, but could you rename this to MIDR_CPU_VAR_REV instead please? > The revision field *is* the bottom 4 bits, so "full" rev doesn't really > make a lot of sense. Yeah, this is that I had in my first version. I wasn't sure on the naming, so I am fine with your proposal. Will resubmit. Thanks, -Robert
Re: [PATCH v2] i2c: do not enable fall back to Host Notify by default
On Wed, Jan 04, 2017 at 08:57:22PM -0800, Dmitry Torokhov wrote: > Falling back unconditionally to HostNotify as primary client's interrupt > breaks some drivers which alter their functionality depending on whether > interrupt is present or not, so let's introduce a board flag telling I2C > core explicitly if we want wired interrupt or HostNotify-based one: > I2C_CLIENT_HOST_NOTIFY. > > For DT-based systems we introduce "host-notify" property that we convert > to I2C_CLIENT_HOST_NOTIFY board flag. > > Tested-by: Benjamin Tissoires > Signed-off-by: Dmitry Torokhov Applied to for-current, thanks! How do we handle driver fixes? Shall I take them via I2C to have the dependency clear? Or can they go seperately?
Re: [PATCH] tpm_tis: override reported C and D timeouts for Atmel 3203
On Thu, Jan 12, 2017 at 07:08:53PM +0100, Maciej S. Szmigiero wrote: > Since commit 1107d065fdf1 ("tpm_tis: Introduce intermediate layer for TPM > access") Atmel 3203 TPM on ThinkPad X61S (TPM firmware version 13.9) no > longer works. > It turns out the initialization proceeds fine until we get and start using > chip-reported timeouts - and the chip reports C and D timeouts of zero. > > Since these are clearly not long enough let's add an override for them > to TPM TIS default values, just as we do for Atmel 3204. > A and B timeouts are set to the same values as the chip normally reports. > > Signed-off-by: Maciej S. Szmigiero > static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = > { > + /* Atmel 3203 */ > + { 0x32031114, { (10*1000), (10*1000), > + (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, > /* Atmel 3204 */ > { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000), > (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, Can you also add a check for 0 timeouts in the core code and print a FW_BUG :\ Jason
Re: [linux-sunxi] Re: [PATCH 2/5] clk: sunxi-ng: add support for V3s CCU
Hi, On Wed, Jan 11, 2017 at 11:55:16AM +0800, Icenowy Zheng wrote: > > 2017年1月11日 02:10于 Maxime Ripard 写道: > > > > On Tue, Jan 03, 2017 at 11:16:26PM +0800, Icenowy Zheng wrote: > > > V3s has a similar but cut-down CCU to H3. > > > > > > Add support for it. > > > > > > Signed-off-by: Icenowy Zheng > > > > It looks like there's nothing different but the clocks that you > > register with the H3, please just use the H3 driver. > > USB gate part is different, and many things have gone. As far as I can see, you're only adding a few clocks, and removing a bunch. This is definitely something that can be dealt with by simply registering a slightly different set of clocks, like we're doing on sun5i. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
[patch net-next] stmmac: indent an if statement
The break statement should be indented one more tab. Signed-off-by: Dan Carpenter diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index ac32f9e..4daa8a3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -191,7 +191,7 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, for_each_child_of_node(np, plat->mdio_node) { if (of_device_is_compatible(plat->mdio_node, "snps,dwmac-mdio")) - break; + break; } }
[PATCH 0/4] n2rng: add support for m5/m7 rng register layout
Commit c1e9b3b0eea1 ("hwrng: n2 - Attach on T5/M5, T7/M7 SPARC CPUs") added config strings to enable the random number generator in the sparc m5 and m7 platforms. This worked fine for client LDoms, but not for the primary LDom, or running on bare metal, because the actual rng hardware layout changed and self-test would now fail, continually spewing error messages on the console. This patch series adds correct support for the new rng register layout, and adds a limiter to the spewing of error messages. Orabug: 25127795 Shannon Nelson (4): n2rng: limit error spewage when self-test fails n2rng: add device data descriptions n2rng: support new hardware register layout n2rng: update version info drivers/char/hw_random/n2-drv.c | 204 +-- drivers/char/hw_random/n2rng.h | 51 -- 2 files changed, 196 insertions(+), 59 deletions(-)
[PATCH 1/4] n2rng: limit error spewage when self-test fails
If the self-test fails, it probably won't actually suddenly start working. Currently, this causes an endless spew of error messages on the console and in the logs, so this patch adds a limiter to the test. Reported-by: Sowmini Varadhan Signed-off-by: Shannon Nelson --- drivers/char/hw_random/n2-drv.c |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 3b06c1d..102560f 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -589,6 +589,7 @@ static void n2rng_work(struct work_struct *work) { struct n2rng *np = container_of(work, struct n2rng, work.work); int err = 0; + static int retries = 4; if (!(np->flags & N2RNG_FLAG_CONTROL)) { err = n2rng_guest_check(np); @@ -606,7 +607,9 @@ static void n2rng_work(struct work_struct *work) dev_info(&np->op->dev, "RNG ready\n"); } - if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN)) + if (--retries == 0) + dev_err(&np->op->dev, "Self-test retries failed, RNG not ready\n"); + else if (err && !(np->flags & N2RNG_FLAG_SHUTDOWN)) schedule_delayed_work(&np->work, HZ * 2); } -- 1.7.1
[PATCH 2/4] n2rng: add device data descriptions
Since we're going to need to keep track of more than just one attribute of the hardware, we'll change the use of the data field from the match struct from a single flag to a struct pointer. This patch adds the struct template and initial descriptions. Signed-off-by: Shannon Nelson --- drivers/char/hw_random/n2-drv.c | 47 -- drivers/char/hw_random/n2rng.h | 15 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 102560f..74c26c7 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -625,24 +625,23 @@ static void n2rng_driver_version(void) static int n2rng_probe(struct platform_device *op) { const struct of_device_id *match; - int multi_capable; int err = -ENOMEM; struct n2rng *np; match = of_match_device(n2rng_match, &op->dev); if (!match) return -EINVAL; - multi_capable = (match->data != NULL); n2rng_driver_version(); np = devm_kzalloc(&op->dev, sizeof(*np), GFP_KERNEL); if (!np) goto out; np->op = op; + np->data = (struct n2rng_template *)match->data; INIT_DELAYED_WORK(&np->work, n2rng_work); - if (multi_capable) + if (np->data->multi_capable) np->flags |= N2RNG_FLAG_MULTI; err = -ENODEV; @@ -673,8 +672,9 @@ static int n2rng_probe(struct platform_device *op) dev_err(&op->dev, "VF RNG lacks rng-#units property\n"); goto out_hvapi_unregister; } - } else + } else { np->num_units = 1; + } dev_info(&op->dev, "Registered RNG HVAPI major %lu minor %lu\n", np->hvapi_major, np->hvapi_minor); @@ -731,30 +731,61 @@ static int n2rng_remove(struct platform_device *op) return 0; } +static struct n2rng_template n2_template = { + .id = N2_n2_rng, + .multi_capable = 0, + .chip_version = 1, +}; + +static struct n2rng_template vf_template = { + .id = N2_vf_rng, + .multi_capable = 1, + .chip_version = 1, +}; + +static struct n2rng_template kt_template = { + .id = N2_kt_rng, + .multi_capable = 1, + .chip_version = 1, +}; + +static struct n2rng_template m4_template = { + .id = N2_m4_rng, + .multi_capable = 1, + .chip_version = 2, +}; + +static struct n2rng_template m7_template = { + .id = N2_m7_rng, + .multi_capable = 1, + .chip_version = 2, +}; + static const struct of_device_id n2rng_match[] = { { .name = "random-number-generator", .compatible = "SUNW,n2-rng", + .data = &n2_template, }, { .name = "random-number-generator", .compatible = "SUNW,vf-rng", - .data = (void *) 1, + .data = &vf_template, }, { .name = "random-number-generator", .compatible = "SUNW,kt-rng", - .data = (void *) 1, + .data = &kt_template, }, { .name = "random-number-generator", .compatible = "ORCL,m4-rng", - .data = (void *) 1, + .data = &m4_template, }, { .name = "random-number-generator", .compatible = "ORCL,m7-rng", - .data = (void *) 1, + .data = &m7_template, }, {}, }; diff --git a/drivers/char/hw_random/n2rng.h b/drivers/char/hw_random/n2rng.h index f244ac8..e41e55a 100644 --- a/drivers/char/hw_random/n2rng.h +++ b/drivers/char/hw_random/n2rng.h @@ -60,6 +60,20 @@ extern unsigned long sun4v_rng_data_read_diag_v2(unsigned long data_ra, extern unsigned long sun4v_rng_data_read(unsigned long data_ra, unsigned long *tick_delta); +enum n2rng_compat_id { + N2_n2_rng, + N2_vf_rng, + N2_kt_rng, + N2_m4_rng, + N2_m7_rng, +}; + +struct n2rng_template { + enum n2rng_compat_id id; + int multi_capable; + int chip_version; +}; + struct n2rng_unit { u64 control[HV_RNG_NUM_CONTROL]; }; @@ -74,6 +88,7 @@ struct n2rng { #define N2RNG_FLAG_SHUTDOWN0x0010 /* Driver unregistering*/ #define N2RNG_FLAG_BUFFER_VALID0x0020 /* u32 buffer holds valid data */ + struct n2rng_template *data; int num_units; struct n2rng_unit *units; -- 1.7.1
[PATCH 3/4] n2rng: support new hardware register layout
Add the new register layout constants and the requisite logic for using them. Signed-off-by: Shannon Nelson --- drivers/char/hw_random/n2-drv.c | 144 +-- drivers/char/hw_random/n2rng.h | 36 +++--- 2 files changed, 134 insertions(+), 46 deletions(-) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index 74c26c7..f0bd5ee 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -302,26 +302,57 @@ static int n2rng_try_read_ctl(struct n2rng *np) return n2rng_hv_err_trans(hv_err); } -#define CONTROL_DEFAULT_BASE \ - ((2 << RNG_CTL_ASEL_SHIFT) |\ -(N2RNG_ACCUM_CYCLES_DEFAULT << RNG_CTL_WAIT_SHIFT) | \ -RNG_CTL_LFSR) - -#define CONTROL_DEFAULT_0 \ - (CONTROL_DEFAULT_BASE | \ -(1 << RNG_CTL_VCO_SHIFT) | \ -RNG_CTL_ES1) -#define CONTROL_DEFAULT_1 \ - (CONTROL_DEFAULT_BASE | \ -(2 << RNG_CTL_VCO_SHIFT) | \ -RNG_CTL_ES2) -#define CONTROL_DEFAULT_2 \ - (CONTROL_DEFAULT_BASE | \ -(3 << RNG_CTL_VCO_SHIFT) | \ -RNG_CTL_ES3) -#define CONTROL_DEFAULT_3 \ - (CONTROL_DEFAULT_BASE | \ -RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3) +static u64 n2rng_control_default(struct n2rng *np, int ctl) +{ + u64 val = 0; + + if (np->data->chip_version == 1) { + val = ((2 << RNG_v1_CTL_ASEL_SHIFT) | + (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v1_CTL_WAIT_SHIFT) | +RNG_CTL_LFSR); + + switch (ctl) { + case 0: + val |= (1 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES1; + break; + case 1: + val |= (2 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES2; + break; + case 2: + val |= (3 << RNG_v1_CTL_VCO_SHIFT) | RNG_CTL_ES3; + break; + case 3: + val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3; + break; + default: + break; + } + + } else { + val = ((2 << RNG_v2_CTL_ASEL_SHIFT) | + (N2RNG_ACCUM_CYCLES_DEFAULT << RNG_v2_CTL_WAIT_SHIFT) | +RNG_CTL_LFSR); + + switch (ctl) { + case 0: + val |= (1 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES1; + break; + case 1: + val |= (2 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES2; + break; + case 2: + val |= (3 << RNG_v2_CTL_VCO_SHIFT) | RNG_CTL_ES3; + break; + case 3: + val |= RNG_CTL_ES1 | RNG_CTL_ES2 | RNG_CTL_ES3; + break; + default: + break; + } + } + + return val; +} static void n2rng_control_swstate_init(struct n2rng *np) { @@ -336,10 +367,10 @@ static void n2rng_control_swstate_init(struct n2rng *np) for (i = 0; i < np->num_units; i++) { struct n2rng_unit *up = &np->units[i]; - up->control[0] = CONTROL_DEFAULT_0; - up->control[1] = CONTROL_DEFAULT_1; - up->control[2] = CONTROL_DEFAULT_2; - up->control[3] = CONTROL_DEFAULT_3; + up->control[0] = n2rng_control_default(np, 0); + up->control[1] = n2rng_control_default(np, 1); + up->control[2] = n2rng_control_default(np, 2); + up->control[3] = n2rng_control_default(np, 3); } np->hv_state = HV_RNG_STATE_UNCONFIGURED; @@ -399,6 +430,7 @@ static int n2rng_data_read(struct hwrng *rng, u32 *data) } else { int err = n2rng_generic_read_data(ra); if (!err) { + np->flags |= N2RNG_FLAG_BUFFER_VALID; np->buffer = np->test_data >> 32; *data = np->test_data & 0x; len = 4; @@ -487,9 +519,21 @@ static void n2rng_dump_test_buffer(struct n2rng *np) static int n2rng_check_selftest_buffer(struct n2rng *np, unsigned long unit) { - u64 val = SELFTEST_VAL; + u64 val; int err, matches, limit; + switch (np->data->id) { + case N2_n2_rng: + case N2_vf_rng: + case N2_kt_rng: + case N2_m4_rng: /* yes, m4 uses the old value */ + val = RNG_v1_SELFTEST_VAL; + break; + default: + val = RNG_v2_SELFTEST_VAL; + break; + } + matches = 0; for (limit = 0; limit < SELFTEST_LOOPS_MAX; limit++) { matches += n2rng_test_buffer_find(np, val); @@ -5
Re: [PATCH] tpm_tis: fix iTPM probe via probe_itpm() function
On Thu, Jan 12, 2017 at 07:12:06PM +0100, Maciej S. Szmigiero wrote: > probe_itpm() function is supposed to send command without an itpm flag set > and if this fails to repeat it, this time with the itpm flag set. > > However, commit 41a5e1cf1fe15 ("tpm/tpm_tis: Split tpm_tis driver into a > core and TCG TIS compliant phy") moved the itpm flag from an "itpm" > variable to a TPM_TIS_ITPM_POSSIBLE chip flag, so setting the > (now function-local) itpm variable no longer had any effect. > > Finally, this function-local itpm variable was removed by > commit 56af322156dbe9 ("tpm/tpm_tis: remove unused itpm variable") > > Tested only on non-iTPM TIS TPM. > > Signed-off-by: Maciej S. Szmigiero could you also change the name of TPM_TIS_ITPM_POSSIBLE to TPM_TIS_ITPM_WORKAROUND ? Reviewed-by: Jason Gunthorpe Jason
[PATCH 4/4] n2rng: update version info
Signed-off-by: Shannon Nelson --- drivers/char/hw_random/n2-drv.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index f0bd5ee..31cbdbb 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -21,11 +21,11 @@ #define DRV_MODULE_NAME"n2rng" #define PFX DRV_MODULE_NAME": " -#define DRV_MODULE_VERSION "0.2" -#define DRV_MODULE_RELDATE "July 27, 2011" +#define DRV_MODULE_VERSION "0.3" +#define DRV_MODULE_RELDATE "Jan 7, 2017" static char version[] = - DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("David S. Miller (da...@davemloft.net)"); MODULE_DESCRIPTION("Niagara2 RNG driver"); @@ -765,7 +765,7 @@ static int n2rng_probe(struct platform_device *op) "multi-unit-capable" : "single-unit"), np->num_units); - np->hwrng.name = "n2rng"; + np->hwrng.name = DRV_MODULE_NAME; np->hwrng.data_read = n2rng_data_read; np->hwrng.priv = (unsigned long) np; -- 1.7.1
Re: [PATCH] Input: silead: use msleep() for long delays
On Thu, Jan 12, 2017 at 10:10:44AM -0800, Dmitry Torokhov wrote: > On Thu, Jan 12, 2017 at 9:46 AM, Hans de Goede wrote: > > Hi, > > > > On 01/12/2017 05:21 PM, Nicholas Mc Guire wrote: > >> > >> the delays here are in the 10 to 20ms range so msleep() will do - no > >> need to burden the highres timer subsystem. > >> > >> Signed-off-by: Nicholas Mc Guire > >> --- > >> > >> Problem found by coccinelle script > >> > >> While msleep(10) has a worst case uncertainty of 10ms (on HZ=100 systems) > >> this seems ok here as the delays are not called frequently (init and > >> reset functions) > > > > > > By the same logic, this is not much of a burden on the high-res timer > > subsys though. > > > >> and the uncertainty of 10ms fits the permitted range of > >> the original usleep_ranges(). > > > > > > Either way this patch is fine with me. > > I'd rather not because next will come a checkpatch warrior and I will > have to convince them why msleep is OK here. And another one, and > another one... :( > there is no checkpatch warning here - checkpatch only throws warnings of range < 20ms if hardcoded but this is in a #define so its fine with respect to checkpatch. But if there are concerns with this - thats fine - its most likely not critical - the goal is to have a consistent usage of highres timers - including limiting there use to the cases where its really needed. thx! hofrat
Re: [PATCH v3] arm64: mm: Fix NOMAP page initialization
On 12.01.17 16:05:36, Will Deacon wrote: > On Mon, Jan 09, 2017 at 12:53:20PM +0100, Robert Richter wrote: > > Kernel compile times (3 runs each): > > > > pfn_valid_within(): > > > > real6m4.088s > > user372m57.607s > > sys 16m55.158s > > > > real6m1.532s > > user372m48.453s > > sys 16m50.370s > > > > real6m4.061s > > user373m18.753s > > sys 16m57.027s > > Did you reboot the machine between each build here, or only when changing > kernel? If the latter, do you see variations in kernel build time by simply > rebooting the same Image? I built it in a loop on the shell, so no reboots between builds. Note that I was building the kernel in /dev/shm to not access harddisks. I think build times should be comparable then since there is no fs caching. -Robert
Re: [PATCH] scripts/spelling.txt: add some typo-words
On Thu, Jan 12, 2017 at 3:34 AM, Jinbum Park wrote: > I wrote a simple script to find new typo not in spelling.txt. > (https://github.com/jinb-park/find-linux-kernel-typo) > > and get following result: > > [ rank ] > 63 paramaters > 18 alignement > 9 strucuture > > > The number means how many files include the typo. > This patch adds these common typo. > > Signed-off-by: Jinbum Park Sounds good to me! Acked-by: Kees Cook -Kees > --- > scripts/spelling.txt | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/scripts/spelling.txt b/scripts/spelling.txt > index 417ede8..201d0ed 100644 > --- a/scripts/spelling.txt > +++ b/scripts/spelling.txt > @@ -74,6 +74,7 @@ algoritms||algorithms > algorrithm||algorithm > algorritm||algorithm > aligment||alignment > +alignement||alignment > allign||align > allocatrd||allocated > allocte||allocate > @@ -752,6 +753,7 @@ pakage||package > pallette||palette > paln||plan > paramameters||parameters > +paramaters||parameters > paramater||parameter > parametes||parameters > parametised||parametrised > @@ -996,6 +998,7 @@ straming||streaming > struc||struct > structres||structures > stuct||struct > +strucuture||structure > stucture||structure > sturcture||structure > subdirectoires||subdirectories > -- > 1.9.1 > -- Kees Cook Nexus Security
Re: Linux 4.9.3
On Thu, Jan 12, 2017 at 06:14:13PM +, Chris Rankin wrote: > Still no sign of the 4.9.3 patches on the FTP site... Oops? Sorry, should be there now. greg k-h
Re: [PATCH 2/3] gpio: davinci: Redesign driver to accommodate ngpios in one gpio chip
On 01/11/2017 08:00 PM, Keerthy wrote: On Wednesday 11 January 2017 11:23 PM, Grygorii Strashko wrote: On 01/10/2017 11:00 PM, Keerthy wrote: The Davinci GPIO driver is implemented to work with one monolithic Davinci GPIO platform device which may have up to Y(144) gpios. The Davinci GPIO driver instantiates number of GPIO chips with max 32 gpio pins per each during initialization and one IRQ domain. So, the current GPIO's opjects structure is: Davinci GPIO controller |- --| ...|--- irq_domain (hwirq [0..143]) |- --| Current driver creates one chip for every 32 GPIOs in a controller. This was a limitation earlier now there is no need for that. Hence redesigning the driver to create one gpio chip for all the ngpio in the controller. |- --|--- irq_domain (hwirq [0..143]). The previous discussion on this can be found here: https://www.spinics.net/lists/linux-omap/msg132869.html nice rework. Thanks! Signed-off-by: Keerthy --- Boot tested on Davinci platform. drivers/gpio/gpio-davinci.c| 127 + [...] #ifdef CONFIG_OF_GPIO -chips[i].chip.of_gpio_n_cells = 2; -chips[i].chip.of_xlate = davinci_gpio_of_xlate; -chips[i].chip.parent = dev; -chips[i].chip.of_node = dev->of_node; +chips->chip.of_gpio_n_cells = 2; +chips->chip.of_xlate = davinci_gpio_of_xlate; I think It's not necessary to have custom .xlate() and it can be removed, then gpiolib will assign default one of_gpio_simple_xlate(). Okay. Can i do that as a separate patch? I think it's ok. +chips->chip.parent = dev; +chips->chip.of_node = dev->of_node; #endif -spin_lock_init(&chips[i].lock); - [...] irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq, "davinci_gpio"); @@ -459,6 +468,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) struct irq_domain*irq_domain = NULL; const struct of_device_id *match; struct irq_chip *irq_chip; +struct davinci_gpio_irq_data *irqdata[MAX_BANKED_IRQS]; You declare irqdata as array here but it has not been used anywhere except for assignment. Could you remove this array and MAX_BANKED_IRQS define? irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, &chips[gpio / 32]); irqdata[bank]); That is hooked as data for each bank. As there is only one controller now and the differentiating parameters per bank is the irqdata data structure with the registers pointer and the bank number. This structure makes it very easy in the irq handler to identify the register sets that need to be modified and the bank irqs. That I understood, but why do you need array here? Seems you can just use struct davinci_gpio_irq_data *irqdata; why can't you use (see below): struct davinci_gpio_irq_data *irqdata; gpio_get_irq_chip_cb_t gpio_get_irq_chip; /* @@ -514,10 +524,8 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) * IRQs, while the others use banked IRQs, would need some setup * tweaks to recognize hardware which can do that. */ [...] @@ -567,8 +575,19 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev) * gpio irqs. Pass the irq bank's corresponding controller to * the chained irq handler. */ +irqdata[bank] = devm_kzalloc(&pdev->dev, + sizeof(struct +davinci_gpio_irq_data), + GFP_KERNEL); irqdata = devm_kzalloc(&pdev->dev, sizeof(struct davinci_gpio_irq_data), GFP_KERNEL); +if (!irqdata[bank]) +return -ENOMEM; + +irqdata[bank]->regs = g; +irqdata[bank]->bank_num = bank; +irqdata[bank]->chip = chips; + irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, - &chips[gpio / 32]); + irqdata[bank]); irq_set_chained_handler_and_data(bank_irq, gpio_irq_handler, irqdata); [...] -- regards, -grygorii
Re: [PATCH] i2c: print correct device invalid address
On Fri, Jan 06, 2017 at 07:02:57PM +0800, John Garry wrote: > In of_i2c_register_device(), when the check for > device address validity fails we print the info.addr, > which has not been assigned properly. > > Fix this by printing the actual invalid address. > > Signed-off-by: John Garry Applied to for-current, thanks!
[PATCH v2 03/26] treewide: Consolidate set_dma_ops() implementations
Now that all set_dma_ops() implementations are identical (ignoring BUG_ON() statements), remove the architecture specific definitions and add a definition in . Signed-off-by: Bart Van Assche Cc: Benjamin Herrenschmidt Cc: Chris Metcalf Cc: David Woodhouse Cc: linux-a...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: linux-kernel@vger.kernel.org Cc: linuxppc-...@lists.ozlabs.org Cc: Paul Mackerras Cc: Russell King --- arch/arm/include/asm/dma-mapping.h | 6 -- arch/powerpc/include/asm/dma-mapping.h | 5 - arch/tile/include/asm/dma-mapping.h| 5 - include/linux/dma-mapping.h| 5 + 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 312f4d0564d6..c7432d647e53 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -31,12 +31,6 @@ static inline const struct dma_map_ops *get_dma_ops(struct device *dev) return __generic_dma_ops(dev); } -static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops) -{ - BUG_ON(!dev); - dev->dma_ops = ops; -} - #define HAVE_ARCH_DMA_SUPPORTED 1 extern int dma_supported(struct device *dev, u64 mask); diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 59fbd4abcbf8..8275603ba4d5 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -91,11 +91,6 @@ static inline const struct dma_map_ops *get_dma_ops(struct device *dev) return dev->dma_ops; } -static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops) -{ - dev->dma_ops = ops; -} - /* * get_dma_offset() * diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h index c0620697eaad..2562995a6ac9 100644 --- a/arch/tile/include/asm/dma-mapping.h +++ b/arch/tile/include/asm/dma-mapping.h @@ -59,11 +59,6 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) static inline void dma_mark_clean(void *addr, size_t size) {} -static inline void set_dma_ops(struct device *dev, const struct dma_map_ops *ops) -{ - dev->dma_ops = ops; -} - static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) { if (!dev->dma_mask) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index f1da68b82c63..e97f23e8b2d9 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -164,6 +164,11 @@ int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, #ifdef CONFIG_HAS_DMA #include +static inline void set_dma_ops(struct device *dev, + const struct dma_map_ops *dma_ops) +{ + dev->dma_ops = dma_ops; +} #else /* * Define the dma api to allow compilation but not linking of -- 2.11.0
[PATCH v2 00/26] IB: Optimize DMA mapping
Hello Doug, As you know there are two sets of DMA mapping operations in the Linux kernel: - One set of DMA mapping operations that is used by most drivers. - Another set of DMA mapping operations that is only used by the RDMA drivers. Having two sets of DMA mapping operations is not only a source of confusion but also a source of unnecessary overhead. The DMA mapping operations are in the hot path so it is important that the overhead of these operations is as low as possible. Hence this patch series that converts the RDMA code to the standard DMA mapping API and thereby eliminates the if (dev->dma_ops) test from the hot path. An additional benefit is that the size of HW and SW drivers that do not use DMA is reduced by switching to dma_virt_ops. The changes compared to version 1 of this patch series are: - Patch "Move dma_ops from archdata into struct device" has been split into three patches. - Patch "treewide: Inline ib_dma_map_*() functions" has been split into 15 patches (one per driver). - A patch has been added that builds dma_noop_ops only for the architectures that need it. - The new dma_virt_ops is only built if it is used by a driver. - In these last 15 patches indentation has been adjusted to keep the arguments aligned with the opening parenthesis. Bart Van Assche (26): treewide: Constify most dma_map_ops structures treewide: Move dma_ops from struct dev_archdata into struct device treewide: Consolidate set_dma_ops() implementations treewide: Consolidate get_dma_ops() implementations lib/dma-noop: Clarify a comment lib/dma-noop: Only build dma_noop_ops for m32r and s390 lib/dma-virt: Add dma_virt_ops IB/hf1: Remove DMA mapping code IB/qib: Remove DMA mapping code IB: Use dma_virt_ops instead of duplicating it RDS: IB: Remove an unused structure member IB: Convert ib_dma_*_coherent() argument type from u64 into dma_addr_t IB/core: Inline ib_dma_map_*() functions IB/mlx4: Inline ib_dma_map_*() functions IB/mlx5: Inline ib_dma_map_*() functions IB/IPoIB: Inline ib_dma_map_*() functions IB/iser: Inline ib_dma_map_*() functions IB/isert: Inline ib_dma_map_*() functions IB/srp: Inline ib_dma_map_*() functions IB/srpt: Inline ib_dma_map_*() functions staging/lustre: Inline ib_dma_map_*() functions nvme-rdma: Inline ib_dma_map_*() functions net/9p: Inline ib_dma_map_*() functions net/rds: Inline ib_dma_map_*() functions xprtrdma: Inline ib_dma_map_*() functions IB/core: Remove ib_dma_map_*() functions arch/alpha/include/asm/dma-mapping.h | 4 +- arch/alpha/kernel/pci-noop.c | 4 +- arch/alpha/kernel/pci_iommu.c | 4 +- arch/arc/include/asm/dma-mapping.h | 4 +- arch/arc/mm/dma.c | 2 +- arch/arm/common/dmabounce.c| 2 +- arch/arm/include/asm/device.h | 1 - arch/arm/include/asm/dma-mapping.h | 20 +- arch/arm/mm/dma-mapping.c | 22 +- arch/arm/xen/mm.c | 4 +- arch/arm64/include/asm/device.h| 1 - arch/arm64/include/asm/dma-mapping.h | 12 +- arch/arm64/mm/dma-mapping.c| 14 +- arch/avr32/include/asm/dma-mapping.h | 4 +- arch/avr32/mm/dma-coherent.c | 2 +- arch/blackfin/include/asm/dma-mapping.h| 4 +- arch/blackfin/kernel/dma-mapping.c | 2 +- arch/c6x/include/asm/dma-mapping.h | 4 +- arch/c6x/kernel/dma.c | 2 +- arch/cris/arch-v32/drivers/pci/dma.c | 2 +- arch/cris/include/asm/dma-mapping.h| 6 +- arch/frv/include/asm/dma-mapping.h | 4 +- arch/frv/mb93090-mb00/pci-dma-nommu.c | 2 +- arch/frv/mb93090-mb00/pci-dma.c| 2 +- arch/h8300/include/asm/dma-mapping.h | 4 +- arch/h8300/kernel/dma.c| 2 +- arch/hexagon/include/asm/dma-mapping.h | 7 +- arch/hexagon/kernel/dma.c | 4 +- arch/ia64/hp/common/hwsw_iommu.c | 4 +- arch/ia64/hp/common/sba_iommu.c| 4 +- arch/ia64/include/asm/dma-mapping.h| 7 +- arch/ia64/include/asm/machvec.h| 4 +- arch/ia64/kernel/dma-mapping.c | 4 +- arch/ia64/kernel/pci-dma.c | 10 +- arch/ia64/kernel/pci-swiotlb.c | 2 +- arch/m32r/Kconfig | 1 + arch/m32r/include/asm/device.h | 1 - arch/m32r/include/asm/dma-mapping.h| 4 +- arch/m68k/include/asm/dma-mapping.h| 4 +- arch/m68k/kernel/dma.c | 2 +- arch/metag/include/asm/dma-mapping.h
[PATCH v2 22/26] nvme-rdma: Inline ib_dma_map_*() functions
Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Cc: Keith Busch --- drivers/nvme/host/rdma.c | 35 +++ drivers/nvme/target/rdma.c | 32 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 208b6a08781c..877ff1982f38 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -207,7 +207,7 @@ static inline size_t nvme_rdma_inline_data_size(struct nvme_rdma_queue *queue) static void nvme_rdma_free_qe(struct ib_device *ibdev, struct nvme_rdma_qe *qe, size_t capsule_size, enum dma_data_direction dir) { - ib_dma_unmap_single(ibdev, qe->dma, capsule_size, dir); + dma_unmap_single(ibdev->dma_device, qe->dma, capsule_size, dir); kfree(qe->data); } @@ -218,8 +218,9 @@ static int nvme_rdma_alloc_qe(struct ib_device *ibdev, struct nvme_rdma_qe *qe, if (!qe->data) return -ENOMEM; - qe->dma = ib_dma_map_single(ibdev, qe->data, capsule_size, dir); - if (ib_dma_mapping_error(ibdev, qe->dma)) { + qe->dma = dma_map_single(ibdev->dma_device, qe->data, capsule_size, +dir); + if (dma_mapping_error(ibdev->dma_device, qe->dma)) { kfree(qe->data); return -ENOMEM; } @@ -895,9 +896,8 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue, } } - ib_dma_unmap_sg(ibdev, req->sg_table.sgl, - req->nents, rq_data_dir(rq) == - WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + dma_unmap_sg(ibdev->dma_device, req->sg_table.sgl, req->nents, + rq_data_dir(rq) == WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE); nvme_cleanup_cmd(rq); sg_free_table_chained(&req->sg_table, true); @@ -1008,7 +1008,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue, req->nents = blk_rq_map_sg(rq->q, rq, req->sg_table.sgl); - count = ib_dma_map_sg(ibdev, req->sg_table.sgl, req->nents, + count = dma_map_sg(ibdev->dma_device, req->sg_table.sgl, req->nents, rq_data_dir(rq) == WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE); if (unlikely(count <= 0)) { sg_free_table_chained(&req->sg_table, true); @@ -1135,7 +1135,8 @@ static void nvme_rdma_submit_async_event(struct nvme_ctrl *arg, int aer_idx) if (WARN_ON_ONCE(aer_idx != 0)) return; - ib_dma_sync_single_for_cpu(dev, sqe->dma, sizeof(*cmd), DMA_TO_DEVICE); + dma_sync_single_for_cpu(dev->dma_device, sqe->dma, sizeof(*cmd), + DMA_TO_DEVICE); memset(cmd, 0, sizeof(*cmd)); cmd->common.opcode = nvme_admin_async_event; @@ -1143,8 +1144,8 @@ static void nvme_rdma_submit_async_event(struct nvme_ctrl *arg, int aer_idx) cmd->common.flags |= NVME_CMD_SGL_METABUF; nvme_rdma_set_sg_null(cmd); - ib_dma_sync_single_for_device(dev, sqe->dma, sizeof(*cmd), - DMA_TO_DEVICE); + dma_sync_single_for_device(dev->dma_device, sqe->dma, sizeof(*cmd), + DMA_TO_DEVICE); ret = nvme_rdma_post_send(queue, sqe, &sge, 1, NULL, false); WARN_ON_ONCE(ret); @@ -1194,7 +1195,8 @@ static int __nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc, int tag) return 0; } - ib_dma_sync_single_for_cpu(ibdev, qe->dma, len, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(ibdev->dma_device, qe->dma, len, + DMA_FROM_DEVICE); /* * AEN requests are special as they don't time out and can * survive any kind of queue freeze and often don't respond to @@ -1207,7 +1209,8 @@ static int __nvme_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc, int tag) &cqe->result); else ret = nvme_rdma_process_nvme_rsp(queue, cqe, wc, tag); - ib_dma_sync_single_for_device(ibdev, qe->dma, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(ibdev->dma_device, qe->dma, len, + DMA_FROM_DEVICE); nvme_rdma_post_recv(queue, qe); return ret; @@ -1455,8 +1458,8 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, return BLK_MQ_RQ_QUEUE_BUSY; dev = queue->device->dev; - ib_dma_sync_single_for_cpu(dev, sqe->dma, - sizeof(struct nvme_command), DMA_TO_DEVICE); + dma_sync_single_for_cpu(dev->dma_device, sqe->dma, + sizeof(struct nvme_command), DMA_TO_DEVICE); ret = nvme_setup_cmd(ns, rq, c); if (ret != BLK_MQ_RQ_QUEUE_OK) @@ -1473,8 +1476,8 @@ static int nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, goto err; } -
[PATCH v2 15/26] IB/mlx5: Inline ib_dma_map_*() functions
Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Acked-by: Leon Romanovsky --- drivers/infiniband/hw/mlx5/mr.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 00175191fdc6..4d3daef6d859 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -1865,9 +1865,9 @@ int mlx5_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, mr->ndescs = 0; - ib_dma_sync_single_for_cpu(ibmr->device, mr->desc_map, - mr->desc_size * mr->max_descs, - DMA_TO_DEVICE); + dma_sync_single_for_cpu(ibmr->device->dma_device, mr->desc_map, + mr->desc_size * mr->max_descs, + DMA_TO_DEVICE); if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS) n = mlx5_ib_sg_to_klms(mr, sg, sg_nents, sg_offset); @@ -1875,9 +1875,9 @@ int mlx5_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, n = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, mlx5_set_page); - ib_dma_sync_single_for_device(ibmr->device, mr->desc_map, - mr->desc_size * mr->max_descs, - DMA_TO_DEVICE); + dma_sync_single_for_device(ibmr->device->dma_device, mr->desc_map, + mr->desc_size * mr->max_descs, + DMA_TO_DEVICE); return n; } -- 2.11.0
[PATCH v2 18/26] IB/isert: Inline ib_dma_map_*() functions
Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg --- drivers/infiniband/ulp/isert/ib_isert.c | 120 +--- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 314e95516068..ca919d472bd5 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -189,9 +189,10 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) rx_desc = isert_conn->rx_descs; for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) { - dma_addr = ib_dma_map_single(ib_dev, (void *)rx_desc, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); - if (ib_dma_mapping_error(ib_dev, dma_addr)) + dma_addr = dma_map_single(ib_dev->dma_device, rx_desc, + ISER_RX_PAYLOAD_SIZE, + DMA_FROM_DEVICE); + if (dma_mapping_error(ib_dev->dma_device, dma_addr)) goto dma_map_fail; rx_desc->dma_addr = dma_addr; @@ -208,8 +209,8 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) dma_map_fail: rx_desc = isert_conn->rx_descs; for (j = 0; j < i; j++, rx_desc++) { - ib_dma_unmap_single(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + dma_unmap_single(ib_dev->dma_device, rx_desc->dma_addr, +ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); } kfree(isert_conn->rx_descs); isert_conn->rx_descs = NULL; @@ -229,8 +230,8 @@ isert_free_rx_descriptors(struct isert_conn *isert_conn) rx_desc = isert_conn->rx_descs; for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) { - ib_dma_unmap_single(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + dma_unmap_single(ib_dev->dma_device, rx_desc->dma_addr, +ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); } kfree(isert_conn->rx_descs); @@ -410,13 +411,12 @@ isert_free_login_buf(struct isert_conn *isert_conn) { struct ib_device *ib_dev = isert_conn->device->ib_device; - ib_dma_unmap_single(ib_dev, isert_conn->login_rsp_dma, - ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE); + dma_unmap_single(ib_dev->dma_device, isert_conn->login_rsp_dma, +ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE); kfree(isert_conn->login_rsp_buf); - ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma, - ISER_RX_PAYLOAD_SIZE, - DMA_FROM_DEVICE); + dma_unmap_single(ib_dev->dma_device, isert_conn->login_req_dma, +ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); kfree(isert_conn->login_req_buf); } @@ -431,10 +431,11 @@ isert_alloc_login_buf(struct isert_conn *isert_conn, if (!isert_conn->login_req_buf) return -ENOMEM; - isert_conn->login_req_dma = ib_dma_map_single(ib_dev, - isert_conn->login_req_buf, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); - ret = ib_dma_mapping_error(ib_dev, isert_conn->login_req_dma); + isert_conn->login_req_dma = dma_map_single(ib_dev->dma_device, + isert_conn->login_req_buf, + ISER_RX_PAYLOAD_SIZE, + DMA_FROM_DEVICE); + ret = dma_mapping_error(ib_dev->dma_device, isert_conn->login_req_dma); if (ret) { isert_err("login_req_dma mapping error: %d\n", ret); isert_conn->login_req_dma = 0; @@ -447,10 +448,11 @@ isert_alloc_login_buf(struct isert_conn *isert_conn, goto out_unmap_login_req_buf; } - isert_conn->login_rsp_dma = ib_dma_map_single(ib_dev, - isert_conn->login_rsp_buf, - ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE); - ret = ib_dma_mapping_error(ib_dev, isert_conn->login_rsp_dma); + isert_conn->login_rsp_dma = dma_map_single(ib_dev->dma_device, + isert_conn->login_rsp_buf, + ISER_RX_PAYLOAD_SIZE, + DMA_TO_DEVICE); + ret = dma_mapping_error(ib_dev->dma_device, isert_conn->login_rsp_dma); if (ret) { isert_err("login_rsp_dma mapping error: %d\n", ret); isert_conn->login_rsp_dma = 0; @@ -462,8 +464,8 @@ isert_alloc_login_buf(struct isert_conn *isert_conn, out_free_login_rsp_bu
[PATCH v2 23/26] net/9p: Inline ib_dma_map_*() functions
Signed-off-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Sagi Grimberg Cc: Eric Van Hensbergen --- net/9p/trans_rdma.c | 24 +++- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 553ed4ecb6a0..b49d5998289e 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -294,8 +294,8 @@ recv_done(struct ib_cq *cq, struct ib_wc *wc) int16_t tag; req = NULL; - ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize, -DMA_FROM_DEVICE); + dma_unmap_single(rdma->cm_id->device->dma_device, c->busa, +client->msize, DMA_FROM_DEVICE); if (wc->status != IB_WC_SUCCESS) goto err_out; @@ -339,9 +339,8 @@ send_done(struct ib_cq *cq, struct ib_wc *wc) struct p9_rdma_context *c = container_of(wc->wr_cqe, struct p9_rdma_context, cqe); - ib_dma_unmap_single(rdma->cm_id->device, - c->busa, c->req->tc->size, - DMA_TO_DEVICE); + dma_unmap_single(rdma->cm_id->device->dma_device, c->busa, +c->req->tc->size, DMA_TO_DEVICE); up(&rdma->sq_sem); kfree(c); } @@ -379,10 +378,9 @@ post_recv(struct p9_client *client, struct p9_rdma_context *c) struct ib_recv_wr wr, *bad_wr; struct ib_sge sge; - c->busa = ib_dma_map_single(rdma->cm_id->device, - c->rc->sdata, client->msize, - DMA_FROM_DEVICE); - if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) + c->busa = dma_map_single(rdma->cm_id->device->dma_device, c->rc->sdata, +client->msize, DMA_FROM_DEVICE); + if (dma_mapping_error(rdma->cm_id->device->dma_device, c->busa)) goto error; c->cqe.done = recv_done; @@ -469,10 +467,10 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) } c->req = req; - c->busa = ib_dma_map_single(rdma->cm_id->device, - c->req->tc->sdata, c->req->tc->size, - DMA_TO_DEVICE); - if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) { + c->busa = dma_map_single(rdma->cm_id->device->dma_device, +c->req->tc->sdata, c->req->tc->size, +DMA_TO_DEVICE); + if (dma_mapping_error(rdma->cm_id->device->dma_device, c->busa)) { err = -EIO; goto send_error; } -- 2.11.0