This is the start of the stable review cycle for the 4.0.9 release.
There are 58 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.0.9-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.0.9-rc1
Frodo Lai <[email protected]>
Input: pixcir_i2c_ts - fix receive error
Zhichang Yuan <[email protected]>
of/pci: Fix pci_address_to_pio() conversion of CPU address to I/O port
Alex Williamson <[email protected]>
PCI: pciehp: Wait for hotplug command completion where necessary
Yinghai Lu <[email protected]>
PCI: Add pci_bus_addr_t
Rafael J. Wysocki <[email protected]>
PCI: Propagate the "ignore hotplug" setting to parent
Uwe Kleine-König <[email protected]>
mtd: dc21285: use raw spinlock functions for nw_gpio_lock
Brian Norris <[email protected]>
mtd: fix: avoid race condition when accessing mtd->usecount
Grygorii Strashko <[email protected]>
leds / PM: fix hibernation on arm when gpio-led used with CPU led trigger
Liu Ying <[email protected]>
video: mxsfb: Make sure axi clock is enabled when accessing registers
Axel Lin <[email protected]>
genirq: devres: Fix testing return value of request_any_context_irq()
Bart Van Assche <[email protected]>
IB/srp: Fix reconnection failure handling
Bart Van Assche <[email protected]>
IB/srp: Fix connection state tracking
Bart Van Assche <[email protected]>
IB/srp: Fix a connection setup race
Bart Van Assche <[email protected]>
IB/srp: Remove an extraneous scsi_host_put() from an error path
Bart Van Assche <[email protected]>
scsi_transport_srp: Fix a race condition
Bart Van Assche <[email protected]>
scsi_transport_srp: Introduce srp_wait_for_queuecommand()
Ezequiel Garcia <[email protected]>
spi: pl022: Specify 'num-cs' property as required in devicetree binding
Gregory CLEMENT <[email protected]>
spi: orion: Fix maximum baud rates for Armada 370/XP
Martin Sperl <[email protected]>
spi: fix race freeing dummy_tx/rx before it is unmapped
Miroslav Benes <[email protected]>
livepatch: add module locking around kallsyms calls
Stefan Wahren <[email protected]>
regulator: core: fix constraints output buffer
Joe Perches <[email protected]>
regulator: max77686: fix gpio_enabled shift wrapping bug
Maxime Coquelin <[email protected]>
regmap: Fix possible shift overflow in regmap_field_init()
Arun Chandran <[email protected]>
regmap: Fix regmap_bulk_read in BE mode
Sagi Grimberg <[email protected]>
iser-target: release stale iser connections
Vlastimil Babka <[email protected]>
mm, thp: respect MPOL_PREFERRED policy with non-local node
Larry Finger <[email protected]>
mm: kmemleak_alloc_percpu() should follow the gfp from per_alloc()
Catalin Marinas <[email protected]>
mm: kmemleak: allow safe memory scanning during kmemleak disabling
Will Deacon <[email protected]>
arm64: vdso: work-around broken ELF toolchains in Makefile
Dave P Martin <[email protected]>
arm64: mm: Fix freeing of the wrong memmap entries with !SPARSEMEM_VMEMMAP
Mark Rutland <[email protected]>
arm64: entry: fix context tracking for el0_sp_pc
Catalin Marinas <[email protected]>
arm64: Do not attempt to use init_mm in reset_context()
Tomas Winkler <[email protected]>
mei: txe: reduce suspend/resume time
Alexander Usyskin <[email protected]>
mei: me: wait for power gating exit confirmation
Vineet Gupta <[email protected]>
ARC: add compiler barrier to LLSC based cmpxchg
Vineet Gupta <[email protected]>
ARC: add smp barriers around atomics per Documentation/atomic_ops.txt
Arnaldo Carvalho de Melo <[email protected]>
tools selftests: Fix 'clean' target with make 3.81
Antonio Ospite <[email protected]>
iio: accel: kxcjk-1013: add the "KXCJ9000" ACPI id
Rafael J. Wysocki <[email protected]>
ACPI / PM: Add missing pm_generic_complete() invocation
Rafael J. Wysocki <[email protected]>
ACPI / init: Switch over platform to the ACPI mode later
Takashi Iwai <[email protected]>
ALSA: hda - Fix the dock headphone output on Fujitsu Lifebook E780
Takashi Iwai <[email protected]>
ALSA: hda - Add headset support to Acer Aspire V5
Alex Deucher <[email protected]>
ALSA: hda - set proper caps for newer AMD hda audio in KB/KV
David Henningsson <[email protected]>
ALSA: hda - Fix Dock Headphone on Thinkpad X250 seen as a Line Out
Takashi Iwai <[email protected]>
ALSA: pcm: Fix pcm_class sysfs output
Ryan Underwood <[email protected]>
Disable write buffering on Toshiba ToPIC95
Brian King <[email protected]>
ipr: Increase default adapter init stage change timeout
Paul E. McKenney <[email protected]>
rcu: Correctly handle non-empty Tiny RCU callback list with none ready
Aaron Lu <[email protected]>
gpio: crystalcove: set IRQCHIP_SKIP_SET_WAKE for the irqchip
Eric W. Biederman <[email protected]>
sysfs: Create mountpoints with sysfs_create_mount_point
Eric W. Biederman <[email protected]>
mnt: Modify fs_fully_visible to deal with locked ro nodev and atime
Eric W. Biederman <[email protected]>
mnt: Refactor the logic for mounting sysfs and proc in a user namespace
Eric W. Biederman <[email protected]>
mnt: Update fs_fully_visible to test for permanently empty directories
Eric W. Biederman <[email protected]>
sysfs: Add support for permanently empty directories to serve as mount points.
Eric W. Biederman <[email protected]>
kernfs: Add support for always empty directories.
Eric W. Biederman <[email protected]>
proc: Allow creating permanently empty directories that serve as mount points
Eric W. Biederman <[email protected]>
sysctl: Allow creating permanently empty directories that serve as mountpoints.
Eric W. Biederman <[email protected]>
fs: Add helper functions for permanently empty directories.
-------------
Diffstat:
Documentation/DMA-API-HOWTO.txt | 29 ++++---
Documentation/DMA-API.txt | 30 +++----
.../devicetree/bindings/spi/spi_pl022.txt | 2 +-
Makefile | 4 +-
arch/arc/include/asm/atomic.h | 21 +++++
arch/arc/include/asm/bitops.h | 19 +++++
arch/arc/include/asm/cmpxchg.h | 26 +++++-
arch/arc/include/asm/spinlock.h | 32 ++++++++
arch/arm64/kernel/entry.S | 1 +
arch/arm64/kernel/vdso/Makefile | 4 +
arch/arm64/mm/context.c | 8 ++
arch/arm64/mm/init.c | 2 +-
arch/s390/hypfs/inode.c | 12 +--
drivers/acpi/bus.c | 56 +++++++++----
drivers/acpi/device_pm.c | 1 +
drivers/base/regmap/regmap.c | 5 +-
drivers/firmware/efi/efi.c | 6 +-
drivers/gpio/gpio-crystalcove.c | 1 +
drivers/iio/accel/kxcjk-1013.c | 1 +
drivers/infiniband/ulp/isert/ib_isert.c | 18 +++-
drivers/infiniband/ulp/srp/ib_srp.c | 83 +++++++++----------
drivers/infiniband/ulp/srp/ib_srp.h | 2 +-
drivers/input/touchscreen/pixcir_i2c_ts.c | 2 +-
drivers/leds/led-class.c | 7 +-
drivers/misc/mei/client.c | 2 +-
drivers/misc/mei/hw-me.c | 59 ++++++++++++-
drivers/misc/mei/hw-txe.c | 33 +++++---
drivers/misc/mei/mei_dev.h | 11 +++
drivers/mtd/maps/dc21285.c | 4 +-
drivers/mtd/mtd_blkdevs.c | 5 ++
drivers/of/address.c | 2 +-
drivers/pci/Kconfig | 4 +
drivers/pci/bus.c | 10 +--
drivers/pci/hotplug/pciehp_hpc.c | 52 ++++++++----
drivers/pci/pci.c | 11 +++
drivers/pci/probe.c | 12 +--
drivers/pcmcia/topic.h | 16 ++++
drivers/regulator/core.c | 2 +-
drivers/regulator/max77686.c | 6 +-
drivers/scsi/ipr.h | 2 +-
drivers/scsi/scsi_transport_srp.c | 58 +++++++------
drivers/spi/spi-orion.c | 25 +++++-
drivers/spi/spi.c | 11 +--
drivers/video/fbdev/mxsfb.c | 68 +++++++++++----
fs/configfs/mount.c | 10 +--
fs/debugfs/inode.c | 11 +--
fs/fuse/inode.c | 9 +-
fs/kernfs/dir.c | 38 ++++++++-
fs/kernfs/inode.c | 2 +
fs/libfs.c | 96 ++++++++++++++++++++++
fs/namespace.c | 31 ++++++-
fs/proc/generic.c | 23 ++++++
fs/proc/inode.c | 4 +
fs/proc/internal.h | 6 ++
fs/proc/proc_sysctl.c | 37 +++++++++
fs/proc/root.c | 9 +-
fs/pstore/inode.c | 12 +--
fs/sysfs/dir.c | 34 ++++++++
fs/sysfs/mount.c | 5 +-
include/linux/acpi.h | 2 +
include/linux/fs.h | 4 +-
include/linux/kernfs.h | 3 +
include/linux/kmemleak.h | 6 +-
include/linux/pci.h | 18 ++--
include/linux/sysctl.h | 3 +
include/linux/sysfs.h | 15 ++++
include/linux/types.h | 12 ++-
init/main.c | 1 +
kernel/cgroup.c | 10 +--
kernel/irq/devres.c | 4 +-
kernel/livepatch/core.c | 18 ++--
kernel/rcu/tiny.c | 5 ++
kernel/sysctl.c | 8 +-
mm/kmemleak.c | 28 +++++--
mm/mempolicy.c | 38 +++++----
mm/percpu.c | 2 +-
security/inode.c | 10 +--
security/selinux/selinuxfs.c | 11 ++-
security/smack/smackfs.c | 8 +-
sound/core/pcm.c | 6 +-
sound/pci/hda/hda_intel.c | 4 +
sound/pci/hda/patch_realtek.c | 25 ++++++
tools/testing/selftests/Makefile | 2 +-
83 files changed, 1006 insertions(+), 329 deletions(-)
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit fbabfd0f4ee2e8847bf56edf481249ad1bb8c44d upstream.
To ensure it is safe to mount proc and sysfs I need to check if
filesystems that are mounted on top of them are mounted on truly empty
directories. Given that some directories can gain entries over time,
knowing that a directory is empty right now is insufficient.
Therefore add supporting infrastructure for permantently empty
directories that proc and sysfs can use when they create mount points
for filesystems and fs_fully_visible can use to test for permanently
empty directories to ensure that nothing will be gained by mounting a
fresh copy of proc or sysfs.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/libfs.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 2 +
2 files changed, 98 insertions(+)
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1093,3 +1093,99 @@ simple_nosetlease(struct file *filp, lon
return -EINVAL;
}
EXPORT_SYMBOL(simple_nosetlease);
+
+
+/*
+ * Operations for a permanently empty directory.
+ */
+static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
+ return ERR_PTR(-ENOENT);
+}
+
+static int empty_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct inode *inode = d_inode(dentry);
+ generic_fillattr(inode, stat);
+ return 0;
+}
+
+static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ return -EPERM;
+}
+
+static int empty_dir_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static ssize_t empty_dir_getxattr(struct dentry *dentry, const char *name,
+ void *value, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static int empty_dir_removexattr(struct dentry *dentry, const char *name)
+{
+ return -EOPNOTSUPP;
+}
+
+static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static const struct inode_operations empty_dir_inode_operations = {
+ .lookup = empty_dir_lookup,
+ .permission = generic_permission,
+ .setattr = empty_dir_setattr,
+ .getattr = empty_dir_getattr,
+ .setxattr = empty_dir_setxattr,
+ .getxattr = empty_dir_getxattr,
+ .removexattr = empty_dir_removexattr,
+ .listxattr = empty_dir_listxattr,
+};
+
+static loff_t empty_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+ /* An empty directory has two entries . and .. at offsets 0 and 1 */
+ return generic_file_llseek_size(file, offset, whence, 2, 2);
+}
+
+static int empty_dir_readdir(struct file *file, struct dir_context *ctx)
+{
+ dir_emit_dots(file, ctx);
+ return 0;
+}
+
+static const struct file_operations empty_dir_operations = {
+ .llseek = empty_dir_llseek,
+ .read = generic_read_dir,
+ .iterate = empty_dir_readdir,
+ .fsync = noop_fsync,
+};
+
+
+void make_empty_dir_inode(struct inode *inode)
+{
+ set_nlink(inode, 2);
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ inode->i_uid = GLOBAL_ROOT_UID;
+ inode->i_gid = GLOBAL_ROOT_GID;
+ inode->i_rdev = 0;
+ inode->i_size = 2;
+ inode->i_blkbits = PAGE_SHIFT;
+ inode->i_blocks = 0;
+
+ inode->i_op = &empty_dir_inode_operations;
+ inode->i_fop = &empty_dir_operations;
+}
+
+bool is_empty_dir_inode(struct inode *inode)
+{
+ return (inode->i_fop == &empty_dir_operations) &&
+ (inode->i_op == &empty_dir_inode_operations);
+}
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2721,6 +2721,8 @@ extern struct dentry *simple_lookup(stru
extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
extern const struct file_operations simple_dir_operations;
extern const struct inode_operations simple_dir_inode_operations;
+extern void make_empty_dir_inode(struct inode *inode);
+extern bool is_empty_dir_inode(struct inode *inode);
struct tree_descr { char *name; const struct file_operations *ops; int mode; };
struct dentry *d_alloc_name(struct dentry *, const char *);
extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit f9bd6733d3f11e24f3949becf277507d422ee1eb upstream.
Add a magic sysctl table sysctl_mount_point that when used to
create a directory forces that directory to be permanently empty.
Update the code to use make_empty_dir_inode when accessing permanently
empty directories.
Update the code to not allow adding to permanently empty directories.
Update /proc/sys/fs/binfmt_misc to be a permanently empty directory.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/proc/proc_sysctl.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/sysctl.h | 3 +++
kernel/sysctl.c | 8 +-------
3 files changed, 41 insertions(+), 7 deletions(-)
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -19,6 +19,28 @@ static const struct inode_operations pro
static const struct file_operations proc_sys_dir_file_operations;
static const struct inode_operations proc_sys_dir_operations;
+/* Support for permanently empty directories */
+
+struct ctl_table sysctl_mount_point[] = {
+ { }
+};
+
+static bool is_empty_dir(struct ctl_table_header *head)
+{
+ return head->ctl_table[0].child == sysctl_mount_point;
+}
+
+static void set_empty_dir(struct ctl_dir *dir)
+{
+ dir->header.ctl_table[0].child = sysctl_mount_point;
+}
+
+static void clear_empty_dir(struct ctl_dir *dir)
+
+{
+ dir->header.ctl_table[0].child = NULL;
+}
+
void proc_sys_poll_notify(struct ctl_table_poll *poll)
{
if (!poll)
@@ -187,6 +209,17 @@ static int insert_header(struct ctl_dir
struct ctl_table *entry;
int err;
+ /* Is this a permanently empty directory? */
+ if (is_empty_dir(&dir->header))
+ return -EROFS;
+
+ /* Am I creating a permanently empty directory? */
+ if (header->ctl_table == sysctl_mount_point) {
+ if (!RB_EMPTY_ROOT(&dir->root))
+ return -EINVAL;
+ set_empty_dir(dir);
+ }
+
dir->header.nreg++;
header->parent = dir;
err = insert_links(header);
@@ -202,6 +235,8 @@ fail:
erase_header(header);
put_links(header);
fail_links:
+ if (header->ctl_table == sysctl_mount_point)
+ clear_empty_dir(dir);
header->parent = NULL;
drop_sysctl_table(&dir->header);
return err;
@@ -419,6 +454,8 @@ static struct inode *proc_sys_make_inode
inode->i_mode |= S_IFDIR;
inode->i_op = &proc_sys_dir_operations;
inode->i_fop = &proc_sys_dir_file_operations;
+ if (is_empty_dir(head))
+ make_empty_dir_inode(inode);
}
out:
return inode;
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -188,6 +188,9 @@ struct ctl_table_header *register_sysctl
void unregister_sysctl_table(struct ctl_table_header * table);
extern int sysctl_init(void);
+
+extern struct ctl_table sysctl_mount_point[];
+
#else /* CONFIG_SYSCTL */
static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
{
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1510,12 +1510,6 @@ static struct ctl_table vm_table[] = {
{ }
};
-#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static struct ctl_table binfmt_misc_table[] = {
- { }
-};
-#endif
-
static struct ctl_table fs_table[] = {
{
.procname = "inode-nr",
@@ -1669,7 +1663,7 @@ static struct ctl_table fs_table[] = {
{
.procname = "binfmt_misc",
.mode = 0555,
- .child = binfmt_misc_table,
+ .child = sysctl_mount_point,
},
#endif
{
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit eb6d38d5427b3ad42f5268da0f1dd31bb0af1264 upstream.
Add a new function proc_create_mount_point that when used to creates a
directory that can not be added to.
Add a new function is_empty_pde to test if a function is a mount
point.
Update the code to use make_empty_dir_inode when reporting
a permanently empty directory to the vfs.
Update the code to not allow adding to permanently empty directories.
Update /proc/openprom and /proc/fs/nfsd to be permanently empty directories.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/proc/generic.c | 23 +++++++++++++++++++++++
fs/proc/inode.c | 4 ++++
fs/proc/internal.h | 6 ++++++
fs/proc/root.c | 4 ++--
4 files changed, 35 insertions(+), 2 deletions(-)
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -373,6 +373,10 @@ static struct proc_dir_entry *__proc_cre
WARN(1, "create '/proc/%s' by hand\n", qstr.name);
return NULL;
}
+ if (is_empty_pde(*parent)) {
+ WARN(1, "attempt to add to permanently empty directory");
+ return NULL;
+ }
ent = kzalloc(sizeof(struct proc_dir_entry) + qstr.len + 1, GFP_KERNEL);
if (!ent)
@@ -455,6 +459,25 @@ struct proc_dir_entry *proc_mkdir(const
}
EXPORT_SYMBOL(proc_mkdir);
+struct proc_dir_entry *proc_create_mount_point(const char *name)
+{
+ umode_t mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ struct proc_dir_entry *ent, *parent = NULL;
+
+ ent = __proc_create(&parent, name, mode, 2);
+ if (ent) {
+ ent->data = NULL;
+ ent->proc_fops = NULL;
+ ent->proc_iops = NULL;
+ if (proc_register(parent, ent) < 0) {
+ kfree(ent);
+ parent->nlink--;
+ ent = NULL;
+ }
+ }
+ return ent;
+}
+
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
struct proc_dir_entry *parent,
const struct file_operations *proc_fops,
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -423,6 +423,10 @@ struct inode *proc_get_inode(struct supe
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
PROC_I(inode)->pde = de;
+ if (is_empty_pde(de)) {
+ make_empty_dir_inode(inode);
+ return inode;
+ }
if (de->mode) {
inode->i_mode = de->mode;
inode->i_uid = de->uid;
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -191,6 +191,12 @@ static inline struct proc_dir_entry *pde
}
extern void pde_put(struct proc_dir_entry *);
+static inline bool is_empty_pde(const struct proc_dir_entry *pde)
+{
+ return S_ISDIR(pde->mode) && !pde->proc_iops;
+}
+struct proc_dir_entry *proc_create_mount_point(const char *name);
+
/*
* inode.c
*/
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -182,10 +182,10 @@ void __init proc_root_init(void)
#endif
proc_mkdir("fs", NULL);
proc_mkdir("driver", NULL);
- proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
+ proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
/* just give it a mountpoint */
- proc_mkdir("openprom", NULL);
+ proc_create_mount_point("openprom");
#endif
proc_tty_init();
proc_mkdir("bus", NULL);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit ea015218f2f7ace2dad9cedd21ed95bdba2886d7 upstream.
Add a new function kernfs_create_empty_dir that can be used to create
directory that can not be modified.
Update the code to use make_empty_dir_inode when reporting a
permanently empty directory to the vfs.
Update the code to not allow adding to permanently empty directories.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/kernfs/dir.c | 38 +++++++++++++++++++++++++++++++++++++-
fs/kernfs/inode.c | 2 ++
include/linux/kernfs.h | 3 +++
3 files changed, 42 insertions(+), 1 deletion(-)
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -592,6 +592,9 @@ int kernfs_add_one(struct kernfs_node *k
goto out_unlock;
ret = -ENOENT;
+ if (parent->flags & KERNFS_EMPTY_DIR)
+ goto out_unlock;
+
if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent))
goto out_unlock;
@@ -783,6 +786,38 @@ struct kernfs_node *kernfs_create_dir_ns
return ERR_PTR(rc);
}
+/**
+ * kernfs_create_empty_dir - create an always empty directory
+ * @parent: parent in which to create a new directory
+ * @name: name of the new directory
+ *
+ * Returns the created node on success, ERR_PTR() value on failure.
+ */
+struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
+ const char *name)
+{
+ struct kernfs_node *kn;
+ int rc;
+
+ /* allocate */
+ kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR);
+ if (!kn)
+ return ERR_PTR(-ENOMEM);
+
+ kn->flags |= KERNFS_EMPTY_DIR;
+ kn->dir.root = parent->dir.root;
+ kn->ns = NULL;
+ kn->priv = NULL;
+
+ /* link in */
+ rc = kernfs_add_one(kn);
+ if (!rc)
+ return kn;
+
+ kernfs_put(kn);
+ return ERR_PTR(rc);
+}
+
static struct dentry *kernfs_iop_lookup(struct inode *dir,
struct dentry *dentry,
unsigned int flags)
@@ -1254,7 +1289,8 @@ int kernfs_rename_ns(struct kernfs_node
mutex_lock(&kernfs_mutex);
error = -ENOENT;
- if (!kernfs_active(kn) || !kernfs_active(new_parent))
+ if (!kernfs_active(kn) || !kernfs_active(new_parent) ||
+ (new_parent->flags & KERNFS_EMPTY_DIR))
goto out;
error = 0;
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -296,6 +296,8 @@ static void kernfs_init_inode(struct ker
case KERNFS_DIR:
inode->i_op = &kernfs_dir_iops;
inode->i_fop = &kernfs_dir_fops;
+ if (kn->flags & KERNFS_EMPTY_DIR)
+ make_empty_dir_inode(inode);
break;
case KERNFS_FILE:
inode->i_size = kn->attr.size;
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -45,6 +45,7 @@ enum kernfs_node_flag {
KERNFS_LOCKDEP = 0x0100,
KERNFS_SUICIDAL = 0x0400,
KERNFS_SUICIDED = 0x0800,
+ KERNFS_EMPTY_DIR = 0x1000,
};
/* @flags for kernfs_create_root() */
@@ -285,6 +286,8 @@ void kernfs_destroy_root(struct kernfs_r
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
const char *name, umode_t mode,
void *priv, const void *ns);
+struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
+ const char *name);
struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
const char *name,
umode_t mode, loff_t size,
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit 87d2846fcf88113fae2341da1ca9a71f0d916f2c upstream.
Add two functions sysfs_create_mount_point and
sysfs_remove_mount_point that hang a permanently empty directory off
of a kobject or remove a permanently emptpy directory hanging from a
kobject. Export these new functions so modular filesystems can use
them.
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/sysfs/dir.c | 34 ++++++++++++++++++++++++++++++++++
include/linux/sysfs.h | 15 +++++++++++++++
2 files changed, 49 insertions(+)
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -121,3 +121,37 @@ int sysfs_move_dir_ns(struct kobject *ko
return kernfs_rename_ns(kn, new_parent, kn->name, new_ns);
}
+
+/**
+ * sysfs_create_mount_point - create an always empty directory
+ * @parent_kobj: kobject that will contain this always empty directory
+ * @name: The name of the always empty directory to add
+ */
+int sysfs_create_mount_point(struct kobject *parent_kobj, const char *name)
+{
+ struct kernfs_node *kn, *parent = parent_kobj->sd;
+
+ kn = kernfs_create_empty_dir(parent, name);
+ if (IS_ERR(kn)) {
+ if (PTR_ERR(kn) == -EEXIST)
+ sysfs_warn_dup(parent, name);
+ return PTR_ERR(kn);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sysfs_create_mount_point);
+
+/**
+ * sysfs_remove_mount_point - remove an always empty directory.
+ * @parent_kobj: kobject that will contain this always empty directory
+ * @name: The name of the always empty directory to remove
+ *
+ */
+void sysfs_remove_mount_point(struct kobject *parent_kobj, const char *name)
+{
+ struct kernfs_node *parent = parent_kobj->sd;
+
+ kernfs_remove_by_name_ns(parent, name, NULL);
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_mount_point);
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -195,6 +195,10 @@ int __must_check sysfs_rename_dir_ns(str
int __must_check sysfs_move_dir_ns(struct kobject *kobj,
struct kobject *new_parent_kobj,
const void *new_ns);
+int __must_check sysfs_create_mount_point(struct kobject *parent_kobj,
+ const char *name);
+void sysfs_remove_mount_point(struct kobject *parent_kobj,
+ const char *name);
int __must_check sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
@@ -283,6 +287,17 @@ static inline int sysfs_move_dir_ns(stru
return 0;
}
+static inline int sysfs_create_mount_point(struct kobject *parent_kobj,
+ const char *name)
+{
+ return 0;
+}
+
+static inline void sysfs_remove_mount_point(struct kobject *parent_kobj,
+ const char *name)
+{
+}
+
static inline int sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns)
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit 7236c85e1be51a9e25ba0f6e087a66ca89605a49 upstream.
fs_fully_visible attempts to make fresh mounts of proc and sysfs give
the mounter no more access to proc and sysfs than if they could have
by creating a bind mount. One aspect of proc and sysfs that makes
this particularly tricky is that there are other filesystems that
typically mount on top of proc and sysfs. As those filesystems are
mounted on empty directories in practice it is safe to ignore them.
However testing to ensure filesystems are mounted on empty directories
has not been something the in kernel data structures have supported so
the current test for an empty directory which checks to see
if nlink <= 2 is a bit lacking.
proc and sysfs have recently been modified to use the new empty_dir
infrastructure to create all of their dedicated mount points. Instead
of testing for S_ISDIR(inode->i_mode) && i_nlink <= 2 to see if a
directory is empty, test for is_empty_dir_inode(inode). That small
change guaranteess mounts found on proc and sysfs really are safe to
ignore, because the directories are not only empty but nothing can
ever be added to them. This guarantees there is nothing to worry
about when mounting proc and sysfs.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/namespace.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3196,9 +3196,8 @@ bool fs_fully_visible(struct file_system
/* Only worry about locked mounts */
if (!(mnt->mnt.mnt_flags & MNT_LOCKED))
continue;
- if (!S_ISDIR(inode->i_mode))
- goto next;
- if (inode->i_nlink > 2)
+ /* Is the directory permanetly empty? */
+ if (!is_empty_dir_inode(inode))
goto next;
}
visible = true;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit 1b852bceb0d111e510d1a15826ecc4a19358d512 upstream.
Fresh mounts of proc and sysfs are a very special case that works very
much like a bind mount. Unfortunately the current structure can not
preserve the MNT_LOCK... mount flags. Therefore refactor the logic
into a form that can be modified to preserve those lock bits.
Add a new filesystem flag FS_USERNS_VISIBLE that requires some mount
of the filesystem be fully visible in the current mount namespace,
before the filesystem may be mounted.
Move the logic for calling fs_fully_visible from proc and sysfs into
fs/namespace.c where it has greater access to mount namespace state.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/namespace.c | 8 +++++++-
fs/proc/root.c | 5 +----
fs/sysfs/mount.c | 5 +----
include/linux/fs.h | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2334,6 +2334,8 @@ unlock:
return err;
}
+static bool fs_fully_visible(struct file_system_type *fs_type);
+
/*
* create a new mount for userspace and request it to be added into the
* namespace's tree
@@ -2365,6 +2367,10 @@ static int do_new_mount(struct path *pat
flags |= MS_NODEV;
mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
}
+ if (type->fs_flags & FS_USERNS_VISIBLE) {
+ if (!fs_fully_visible(type))
+ return -EPERM;
+ }
}
mnt = vfs_kern_mount(type, flags, name, data);
@@ -3166,7 +3172,7 @@ bool current_chrooted(void)
return chrooted;
}
-bool fs_fully_visible(struct file_system_type *type)
+static bool fs_fully_visible(struct file_system_type *type)
{
struct mnt_namespace *ns = current->nsproxy->mnt_ns;
struct mount *mnt;
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -112,9 +112,6 @@ static struct dentry *proc_mount(struct
ns = task_active_pid_ns(current);
options = data;
- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
- return ERR_PTR(-EPERM);
-
/* Does the mounter have privilege over the pid namespace? */
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
return ERR_PTR(-EPERM);
@@ -159,7 +156,7 @@ static struct file_system_type proc_fs_t
.name = "proc",
.mount = proc_mount,
.kill_sb = proc_kill_sb,
- .fs_flags = FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};
void __init proc_root_init(void)
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -31,9 +31,6 @@ static struct dentry *sysfs_mount(struct
bool new_sb;
if (!(flags & MS_KERNMOUNT)) {
- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
- return ERR_PTR(-EPERM);
-
if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
return ERR_PTR(-EPERM);
}
@@ -58,7 +55,7 @@ static struct file_system_type sysfs_fs_
.name = "sysfs",
.mount = sysfs_mount,
.kill_sb = sysfs_kill_sb,
- .fs_flags = FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};
int __init sysfs_init(void)
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1863,6 +1863,7 @@ struct file_system_type {
#define FS_HAS_SUBTYPE 4
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
+#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
@@ -1950,7 +1951,6 @@ extern int vfs_ustat(dev_t, struct kstat
extern int freeze_super(struct super_block *super);
extern int thaw_super(struct super_block *super);
extern bool our_mnt(struct vfsmount *mnt);
-extern bool fs_fully_visible(struct file_system_type *);
extern int current_umask(void);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit 8c6cf9cc829fcd0b179b59f7fe288941d0e31108 upstream.
Ignore an existing mount if the locked readonly, nodev or atime
attributes are less permissive than the desired attributes
of the new mount.
On success ensure the new mount locks all of the same readonly, nodev and
atime attributes as the old mount.
The nosuid and noexec attributes are not checked here as this change
is destined for stable and enforcing those attributes causes a
regression in lxc and libvirt-lxc where those applications will not
start and there are no known executables on sysfs or proc and no known
way to create exectuables without code modifications
Fixes: e51db73532955 ("userns: Better restrictions on when proc and sysfs can be mounted")
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/namespace.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2334,7 +2334,7 @@ unlock:
return err;
}
-static bool fs_fully_visible(struct file_system_type *fs_type);
+static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags);
/*
* create a new mount for userspace and request it to be added into the
@@ -2368,7 +2368,7 @@ static int do_new_mount(struct path *pat
mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
}
if (type->fs_flags & FS_USERNS_VISIBLE) {
- if (!fs_fully_visible(type))
+ if (!fs_fully_visible(type, &mnt_flags))
return -EPERM;
}
}
@@ -3172,9 +3172,10 @@ bool current_chrooted(void)
return chrooted;
}
-static bool fs_fully_visible(struct file_system_type *type)
+static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
{
struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+ int new_flags = *new_mnt_flags;
struct mount *mnt;
bool visible = false;
@@ -3193,6 +3194,19 @@ static bool fs_fully_visible(struct file
if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
continue;
+ /* Verify the mount flags are equal to or more permissive
+ * than the proposed new mount.
+ */
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
+ !(new_flags & MNT_READONLY))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
+ !(new_flags & MNT_NODEV))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
+ ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
+ continue;
+
/* This mount is not fully visible if there are any
* locked child mounts that cover anything except for
* empty directories.
@@ -3206,6 +3220,10 @@ static bool fs_fully_visible(struct file
if (!is_empty_dir_inode(inode))
goto next;
}
+ /* Preserve the locked attributes */
+ *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
+ MNT_LOCK_NODEV | \
+ MNT_LOCK_ATIME);
visible = true;
goto found;
next: ;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Eric W. Biederman" <[email protected]>
commit f9bb48825a6b5d02f4cabcc78967c75db903dcdc upstream.
This allows for better documentation in the code and
it allows for a simpler and fully correct version of
fs_fully_visible to be written.
The mount points converted and their filesystems are:
/sys/hypervisor/s390/ s390_hypfs
/sys/kernel/config/ configfs
/sys/kernel/debug/ debugfs
/sys/firmware/efi/efivars/ efivarfs
/sys/fs/fuse/connections/ fusectl
/sys/fs/pstore/ pstore
/sys/kernel/tracing/ tracefs
/sys/fs/cgroup/ cgroup
/sys/kernel/security/ securityfs
/sys/fs/selinux/ selinuxfs
/sys/fs/smackfs/ smackfs
Acked-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/s390/hypfs/inode.c | 12 ++++--------
drivers/firmware/efi/efi.c | 6 ++----
fs/configfs/mount.c | 10 ++++------
fs/debugfs/inode.c | 11 ++++-------
fs/fuse/inode.c | 9 +++------
fs/pstore/inode.c | 12 ++++--------
kernel/cgroup.c | 10 ++++------
security/inode.c | 10 ++++------
security/selinux/selinuxfs.c | 11 +++++------
security/smack/smackfs.c | 8 ++++----
10 files changed, 38 insertions(+), 61 deletions(-)
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -458,8 +458,6 @@ static const struct super_operations hyp
.show_options = hypfs_show_options,
};
-static struct kobject *s390_kobj;
-
static int __init hypfs_init(void)
{
int rc;
@@ -483,18 +481,16 @@ static int __init hypfs_init(void)
rc = -ENODATA;
goto fail_hypfs_sprp_exit;
}
- s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
- if (!s390_kobj) {
- rc = -ENOMEM;
+ rc = sysfs_create_mount_point(hypervisor_kobj, "s390");
+ if (rc)
goto fail_hypfs_diag0c_exit;
- }
rc = register_filesystem(&hypfs_type);
if (rc)
goto fail_filesystem;
return 0;
fail_filesystem:
- kobject_put(s390_kobj);
+ sysfs_remove_mount_point(hypervisor_kobj, "s390");
fail_hypfs_diag0c_exit:
hypfs_diag0c_exit();
fail_hypfs_sprp_exit:
@@ -512,7 +508,7 @@ fail_dbfs_exit:
static void __exit hypfs_exit(void)
{
unregister_filesystem(&hypfs_type);
- kobject_put(s390_kobj);
+ sysfs_remove_mount_point(hypervisor_kobj, "s390");
hypfs_diag0c_exit();
hypfs_sprp_exit();
hypfs_vm_exit();
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -65,7 +65,6 @@ static int __init parse_efi_cmdline(char
early_param("efi", parse_efi_cmdline);
static struct kobject *efi_kobj;
-static struct kobject *efivars_kobj;
/*
* Let's not leave out systab information that snuck into
@@ -212,10 +211,9 @@ static int __init efisubsys_init(void)
goto err_remove_group;
/* and the standard mountpoint for efivarfs */
- efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
- if (!efivars_kobj) {
+ error = sysfs_create_mount_point(efi_kobj, "efivars");
+ if (error) {
pr_err("efivars: Subsystem registration failed.\n");
- error = -ENOMEM;
goto err_remove_group;
}
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -129,8 +129,6 @@ void configfs_release_fs(void)
}
-static struct kobject *config_kobj;
-
static int __init configfs_init(void)
{
int err = -ENOMEM;
@@ -141,8 +139,8 @@ static int __init configfs_init(void)
if (!configfs_dir_cachep)
goto out;
- config_kobj = kobject_create_and_add("config", kernel_kobj);
- if (!config_kobj)
+ err = sysfs_create_mount_point(kernel_kobj, "config");
+ if (err)
goto out2;
err = register_filesystem(&configfs_fs_type);
@@ -152,7 +150,7 @@ static int __init configfs_init(void)
return 0;
out3:
pr_err("Unable to register filesystem!\n");
- kobject_put(config_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "config");
out2:
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
@@ -163,7 +161,7 @@ out:
static void __exit configfs_exit(void)
{
unregister_filesystem(&configfs_fs_type);
- kobject_put(config_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "config");
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
}
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -713,20 +713,17 @@ bool debugfs_initialized(void)
}
EXPORT_SYMBOL_GPL(debugfs_initialized);
-
-static struct kobject *debug_kobj;
-
static int __init debugfs_init(void)
{
int retval;
- debug_kobj = kobject_create_and_add("debug", kernel_kobj);
- if (!debug_kobj)
- return -EINVAL;
+ retval = sysfs_create_mount_point(kernel_kobj, "debug");
+ if (retval)
+ return retval;
retval = register_filesystem(&debug_fs_type);
if (retval)
- kobject_put(debug_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "debug");
else
debugfs_registered = true;
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1238,7 +1238,6 @@ static void fuse_fs_cleanup(void)
}
static struct kobject *fuse_kobj;
-static struct kobject *connections_kobj;
static int fuse_sysfs_init(void)
{
@@ -1250,11 +1249,9 @@ static int fuse_sysfs_init(void)
goto out_err;
}
- connections_kobj = kobject_create_and_add("connections", fuse_kobj);
- if (!connections_kobj) {
- err = -ENOMEM;
+ err = sysfs_create_mount_point(fuse_kobj, "connections");
+ if (err)
goto out_fuse_unregister;
- }
return 0;
@@ -1266,7 +1263,7 @@ static int fuse_sysfs_init(void)
static void fuse_sysfs_cleanup(void)
{
- kobject_put(connections_kobj);
+ sysfs_remove_mount_point(fuse_kobj, "connections");
kobject_put(fuse_kobj);
}
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -458,22 +458,18 @@ static struct file_system_type pstore_fs
.kill_sb = pstore_kill_sb,
};
-static struct kobject *pstore_kobj;
-
static int __init init_pstore_fs(void)
{
- int err = 0;
+ int err;
/* Create a convenient mount point for people to access pstore */
- pstore_kobj = kobject_create_and_add("pstore", fs_kobj);
- if (!pstore_kobj) {
- err = -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "pstore");
+ if (err)
goto out;
- }
err = register_filesystem(&pstore_fs_type);
if (err < 0)
- kobject_put(pstore_kobj);
+ sysfs_remove_mount_point(fs_kobj, "pstore");
out:
return err;
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1924,8 +1924,6 @@ static struct file_system_type cgroup_fs
.kill_sb = cgroup_kill_sb,
};
-static struct kobject *cgroup_kobj;
-
/**
* task_cgroup_path - cgroup path of a task in the first cgroup hierarchy
* @task: target task
@@ -5042,13 +5040,13 @@ int __init cgroup_init(void)
}
}
- cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
- if (!cgroup_kobj)
- return -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "cgroup");
+ if (err)
+ return err;
err = register_filesystem(&cgroup_fs_type);
if (err < 0) {
- kobject_put(cgroup_kobj);
+ sysfs_remove_mount_point(fs_kobj, "cgroup");
return err;
}
--- a/security/inode.c
+++ b/security/inode.c
@@ -215,19 +215,17 @@ void securityfs_remove(struct dentry *de
}
EXPORT_SYMBOL_GPL(securityfs_remove);
-static struct kobject *security_kobj;
-
static int __init securityfs_init(void)
{
int retval;
- security_kobj = kobject_create_and_add("security", kernel_kobj);
- if (!security_kobj)
- return -EINVAL;
+ retval = sysfs_create_mount_point(kernel_kobj, "security");
+ if (retval)
+ return retval;
retval = register_filesystem(&fs_type);
if (retval)
- kobject_put(security_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "security");
return retval;
}
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1853,7 +1853,6 @@ static struct file_system_type sel_fs_ty
};
struct vfsmount *selinuxfs_mount;
-static struct kobject *selinuxfs_kobj;
static int __init init_sel_fs(void)
{
@@ -1862,13 +1861,13 @@ static int __init init_sel_fs(void)
if (!selinux_enabled)
return 0;
- selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
- if (!selinuxfs_kobj)
- return -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "selinux");
+ if (err)
+ return err;
err = register_filesystem(&sel_fs_type);
if (err) {
- kobject_put(selinuxfs_kobj);
+ sysfs_remove_mount_point(fs_kobj, "selinux");
return err;
}
@@ -1887,7 +1886,7 @@ __initcall(init_sel_fs);
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
void exit_sel_fs(void)
{
- kobject_put(selinuxfs_kobj);
+ sysfs_remove_mount_point(fs_kobj, "selinux");
kern_unmount(selinuxfs_mount);
unregister_filesystem(&sel_fs_type);
}
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -2150,16 +2150,16 @@ static const struct file_operations smk_
.llseek = generic_file_llseek,
};
-static struct kset *smackfs_kset;
/**
* smk_init_sysfs - initialize /sys/fs/smackfs
*
*/
static int smk_init_sysfs(void)
{
- smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj);
- if (!smackfs_kset)
- return -ENOMEM;
+ int err;
+ err = sysfs_create_mount_point(fs_kobj, "smackfs");
+ if (err)
+ return err;
return 0;
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aaron Lu <[email protected]>
commit 61e749d7e1627d375156553ea0ae83c4f6bb5a9b upstream.
The CrystalCove GPIO irqchip doesn't have irq_set_wake callback defined
so we should set IRQCHIP_SKIP_SET_WAKE for it or it would cause an irq
desc's wake_depth unbalanced warning during system resume phase from the
gpio_keys driver, which is the driver for the power button of the ASUS
T100 laptop.
Signed-off-by: Aaron Lu <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/gpio/gpio-crystalcove.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpio/gpio-crystalcove.c
+++ b/drivers/gpio/gpio-crystalcove.c
@@ -250,6 +250,7 @@ static struct irq_chip crystalcove_irqch
.irq_set_type = crystalcove_irq_type,
.irq_bus_lock = crystalcove_bus_lock,
.irq_bus_sync_unlock = crystalcove_bus_sync_unlock,
+ .flags = IRQCHIP_SKIP_SET_WAKE,
};
static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data)
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Paul E. McKenney" <[email protected]>
commit 6e91f8cb138625be96070b778d9ba71ce520ea7e upstream.
If, at the time __rcu_process_callbacks() is invoked, there are callbacks
in Tiny RCU's callback list, but none of them are ready to be invoked,
the current list-management code will knit the non-ready callbacks out
of the list. This can result in hangs and possibly worse. This commit
therefore inserts a check for there being no callbacks that can be
invoked immediately.
This bug is unlikely to occur -- you have to get a new callback between
the time rcu_sched_qs() or rcu_bh_qs() was called, but before we get to
__rcu_process_callbacks(). It was detected by the addition of RCU-bh
testing to rcutorture, which in turn was instigated by Iftekhar Ahmed's
mutation testing. Although this bug was made much more likely by
915e8a4fe45e (rcu: Remove fastpath from __rcu_process_callbacks()), this
did not cause the bug, but rather made it much more probable. That
said, it takes more than 40 hours of rcutorture testing, on average,
for this bug to appear, so this fix cannot be considered an emergency.
Signed-off-by: Paul E. McKenney <[email protected]>
Reviewed-by: Josh Triplett <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/rcu/tiny.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -182,6 +182,11 @@ static void __rcu_process_callbacks(stru
/* Move the ready-to-invoke callbacks to a local list. */
local_irq_save(flags);
+ if (rcp->donetail == &rcp->rcucblist) {
+ /* No callbacks ready, so just leave. */
+ local_irq_restore(flags);
+ return;
+ }
RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, rcp->qlen, -1));
list = rcp->rcucblist;
rcp->rcucblist = *rcp->donetail;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit 45c44b5ff9caa743ed9c2bfd44307c536c9caf1e upstream.
Increase the default init stage change timeout from 15 seconds to 30 seconds.
This resolves issues we have seen with some adapters not transitioning
to the first init stage within 15 seconds, which results in adapter
initialization failures.
Signed-off-by: Brian King <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/ipr.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -268,7 +268,7 @@
#define IPR_RUNTIME_RESET 0x40000000
#define IPR_IPL_INIT_MIN_STAGE_TIME 5
-#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 15
+#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 30
#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0
#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000
#define IPR_IPL_INIT_STAGE_MASK 0xff000000
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Underwood <[email protected]>
commit 2fb22a8042fe96b4220843f79241c116d90922c4 upstream.
Disable write buffering on the Toshiba ToPIC95 if it is enabled by
somebody (it is not supposed to be a power-on default according to
the datasheet). On the ToPIC95, practically no 32-bit Cardbus card
will work under heavy load without locking up the whole system if
this is left enabled. I tried about a dozen. It does not affect
16-bit cards. This is similar to the O2 bugs in early controller
revisions it seems.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=55961
Signed-off-by: Ryan C. Underwood <[email protected]>
Signed-off-by: Dominik Brodowski <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pcmcia/topic.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/drivers/pcmcia/topic.h
+++ b/drivers/pcmcia/topic.h
@@ -104,6 +104,9 @@
#define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */
#define TOPIC_EXCA_IFC_33V_ENA 0x01
+#define TOPIC_PCI_CFG_PPBCN 0x3e /* 16-bit */
+#define TOPIC_PCI_CFG_PPBCN_WBEN 0x0400
+
static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
@@ -138,6 +141,7 @@ static int topic97_override(struct yenta
static int topic95_override(struct yenta_socket *socket)
{
u8 fctrl;
+ u16 ppbcn;
/* enable 3.3V support for 16bit cards */
fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL);
@@ -146,6 +150,18 @@ static int topic95_override(struct yenta
/* tell yenta to use exca registers to power 16bit cards */
socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF;
+ /* Disable write buffers to prevent lockups under load with numerous
+ Cardbus cards, observed on Tecra 500CDT and reported elsewhere on the
+ net. This is not a power-on default according to the datasheet
+ but some BIOSes seem to set it. */
+ if (pci_read_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, &ppbcn) == 0
+ && socket->dev->revision <= 7
+ && (ppbcn & TOPIC_PCI_CFG_PPBCN_WBEN)) {
+ ppbcn &= ~TOPIC_PCI_CFG_PPBCN_WBEN;
+ pci_write_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, ppbcn);
+ dev_info(&socket->dev->dev, "Disabled ToPIC95 Cardbus write buffers.\n");
+ }
+
return 0;
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 60b93030b44a8c2cd015cebe5624fd7552ec67ec upstream.
The pcm_class sysfs of each PCM substream gives only "none" since the
recent code change to embed the struct device. Fix the code to point
directly to the embedded device object properly.
Fixes: ef46c7af93f9 ('ALSA: pcm: Embed struct device')
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/core/pcm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1044,7 +1044,8 @@ void snd_pcm_detach_substream(struct snd
static ssize_t show_pcm_class(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct snd_pcm *pcm;
+ struct snd_pcm_str *pstr = container_of(dev, struct snd_pcm_str, dev);
+ struct snd_pcm *pcm = pstr->pcm;
const char *str;
static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
[SNDRV_PCM_CLASS_GENERIC] = "generic",
@@ -1053,8 +1054,7 @@ static ssize_t show_pcm_class(struct dev
[SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
};
- if (! (pcm = dev_get_drvdata(dev)) ||
- pcm->dev_class > SNDRV_PCM_CLASS_LAST)
+ if (pcm->dev_class > SNDRV_PCM_CLASS_LAST)
str = "none";
else
str = strs[pcm->dev_class];
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Henningsson <[email protected]>
commit ec56af67a10a0d82b79027878a81fce08d002d50 upstream.
Thinkpad X250, when attached to a dock, has two headphone outs but
no line out. Make sure we don't try to turn this into one headphone
and one line out (since that disables the headphone amp on the dock).
Alsa-info at http://www.alsa-project.org/db/?f=36f8764e1d782397928feec715d0ef90dfddd4c1
Signed-off-by: David Henningsson <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/patch_realtek.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4421,6 +4421,7 @@ enum {
ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC292_FIXUP_TPT440_DOCK,
+ ALC292_FIXUP_TPT440_DOCK2,
ALC283_FIXUP_BXBT2807_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS,
@@ -4864,6 +4865,12 @@ static const struct hda_fixup alc269_fix
.chain_id = ALC269_FIXUP_HEADSET_MODE
},
[ALC292_FIXUP_TPT440_DOCK] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
+ .chained = true,
+ .chain_id = ALC292_FIXUP_TPT440_DOCK2
+ },
+ [ALC292_FIXUP_TPT440_DOCK2] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x16, 0x21211010 }, /* dock headphone */
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 650474fb737c3e0ea0f6ab8e43c2cd161080ce5c upstream.
Fixes audio problems on newer asics.
Noticed by: Kelly Anderson <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/hda_intel.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2056,6 +2056,8 @@ static const struct pci_device_id azx_id
{ PCI_DEVICE(0x1022, 0x780d),
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
/* ATI HDMI */
+ { PCI_DEVICE(0x1002, 0x1308),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
{ PCI_DEVICE(0x1002, 0x793b),
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
{ PCI_DEVICE(0x1002, 0x7919),
@@ -2064,6 +2066,8 @@ static const struct pci_device_id azx_id
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
{ PCI_DEVICE(0x1002, 0x970f),
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ { PCI_DEVICE(0x1002, 0x9840),
+ .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
{ PCI_DEVICE(0x1002, 0xaa00),
.driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
{ PCI_DEVICE(0x1002, 0xaa08),
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 7819717b11346b8a5420b223b46600e394049c66 upstream.
Acer Aspire V5 with ALC282 codec needs the similar quirk like Dell
laptops to support the headset mic. The headset mic pin is 0x19 and
it's not exposed by BIOS, thus we need to fix the pincfg as well.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96201
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/patch_realtek.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4394,6 +4394,7 @@ enum {
ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
ALC269_FIXUP_HEADSET_MODE,
ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
+ ALC269_FIXUP_ASPIRE_HEADSET_MIC,
ALC269_FIXUP_ASUS_X101_FUNC,
ALC269_FIXUP_ASUS_X101_VERB,
ALC269_FIXUP_ASUS_X101,
@@ -4663,6 +4664,15 @@ static const struct hda_fixup alc269_fix
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode_no_hp_mic,
},
+ [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC269_FIXUP_HEADSET_MODE,
+ },
[ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
@@ -4937,6 +4947,8 @@ static const struct snd_pci_quirk alc269
SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
+ SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 4df3fd1700abbb53bd874143dfd1f9ac9e7cbf4b upstream.
Fujitsu Lifebook E780 sets the sequence number 0x0f to only only of
the two headphones, thus the driver tries to assign another as the
line-out, and this results in the inconsistent mapping between the
created jack ctl and the actual I/O. Due to this, PulseAudio doesn't
handle it properly and gets the silent output.
The fix is to ignore the non-HP sequencer checks.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=99681
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/patch_realtek.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4374,6 +4374,7 @@ enum {
ALC269_FIXUP_LIFEBOOK,
ALC269_FIXUP_LIFEBOOK_EXTMIC,
ALC269_FIXUP_LIFEBOOK_HP_PIN,
+ ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
ALC269_FIXUP_AMIC,
ALC269_FIXUP_DMIC,
ALC269VB_FIXUP_AMIC,
@@ -4536,6 +4537,10 @@ static const struct hda_fixup alc269_fix
{ }
},
},
+ [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
+ },
[ALC269_FIXUP_AMIC] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
@@ -5046,6 +5051,7 @@ static const struct snd_pci_quirk alc269
SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
+ SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Rafael J. Wysocki" <[email protected]>
commit b064a8fa77dfead647564c46ac8fc5b13bd1ab73 upstream.
Commit 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before
timekeeping_init()" moved the ACPI subsystem initialization,
including the ACPI mode enabling, to an earlier point in the
initialization sequence, to allow the timekeeping subsystem
use ACPI early. Unfortunately, that resulted in boot regressions
on some systems and the early ACPI initialization was moved toward
its original position in the kernel initialization code by commit
c4e1acbb35e4 "ACPI / init: Invoke early ACPI initialization later".
However, that turns out to be insufficient, as boot is still broken
on the Tyan S8812 mainboard.
To fix that issue, split the ACPI early initialization code into
two pieces so the majority of it still located in acpi_early_init()
and the part switching over the platform into the ACPI mode goes into
a new function, acpi_subsystem_init(), executed at the original early
ACPI initialization spot.
That fixes the Tyan S8812 boot problem, but still allows ACPI
tables to be loaded earlier which is useful to the EFI code in
efi_enter_virtual_mode().
Link: https://bugzilla.kernel.org/show_bug.cgi?id=97141
Fixes: 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before timekeeping_init()"
Reported-and-tested-by: Marius Tolzmann <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Acked-by: Toshi Kani <[email protected]>
Reviewed-by: Hanjun Guo <[email protected]>
Reviewed-by: Lee, Chun-Yi <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/acpi/bus.c | 56 +++++++++++++++++++++++++++++++++++++--------------
include/linux/acpi.h | 2 +
init/main.c | 1
3 files changed, 44 insertions(+), 15 deletions(-)
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -467,6 +467,16 @@ static int __init acpi_bus_init_irq(void
return 0;
}
+/**
+ * acpi_early_init - Initialize ACPICA and populate the ACPI namespace.
+ *
+ * The ACPI tables are accessible after this, but the handling of events has not
+ * been initialized and the global lock is not available yet, so AML should not
+ * be executed at this point.
+ *
+ * Doing this before switching the EFI runtime services to virtual mode allows
+ * the EfiBootServices memory to be freed slightly earlier on boot.
+ */
void __init acpi_early_init(void)
{
acpi_status status;
@@ -530,26 +540,42 @@ void __init acpi_early_init(void)
acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
}
#endif
+ return;
+
+ error0:
+ disable_acpi();
+}
+
+/**
+ * acpi_subsystem_init - Finalize the early initialization of ACPI.
+ *
+ * Switch over the platform to the ACPI mode (if possible), initialize the
+ * handling of ACPI events, install the interrupt and global lock handlers.
+ *
+ * Doing this too early is generally unsafe, but at the same time it needs to be
+ * done before all things that really depend on ACPI. The right spot appears to
+ * be before finalizing the EFI initialization.
+ */
+void __init acpi_subsystem_init(void)
+{
+ acpi_status status;
+
+ if (acpi_disabled)
+ return;
status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
- goto error0;
+ disable_acpi();
+ } else {
+ /*
+ * If the system is using ACPI then we can be reasonably
+ * confident that any regulators are managed by the firmware
+ * so tell the regulator core it has everything it needs to
+ * know.
+ */
+ regulator_has_full_constraints();
}
-
- /*
- * If the system is using ACPI then we can be reasonably
- * confident that any regulators are managed by the firmware
- * so tell the regulator core it has everything it needs to
- * know.
- */
- regulator_has_full_constraints();
-
- return;
-
- error0:
- disable_acpi();
- return;
}
static int __init acpi_bus_init(void)
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -428,6 +428,7 @@ extern acpi_status acpi_pci_osc_control_
#define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82
extern void acpi_early_init(void);
+extern void acpi_subsystem_init(void);
extern int acpi_nvs_register(__u64 start, __u64 size);
@@ -477,6 +478,7 @@ static inline const char *acpi_dev_name(
}
static inline void acpi_early_init(void) { }
+static inline void acpi_subsystem_init(void) { }
static inline int early_acpi_boot_init(void)
{
--- a/init/main.c
+++ b/init/main.c
@@ -661,6 +661,7 @@ asmlinkage __visible void __init start_k
check_bugs();
+ acpi_subsystem_init();
sfi_init_late();
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Rafael J. Wysocki" <[email protected]>
commit 3d56402d3fa8d10749eeb36293dd1992bd5ad0c3 upstream.
Add missing invocation of pm_generic_complete() to
acpi_subsys_complete() to allow ->complete callbacks provided
by the drivers of devices using the ACPI PM domain to be executed
during system resume.
Fixes: f25c0ae2b4c4 (ACPI / PM: Avoid resuming devices in ACPI PM domain during system suspend)
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/acpi/device_pm.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -953,6 +953,7 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
*/
void acpi_subsys_complete(struct device *dev)
{
+ pm_generic_complete(dev);
/*
* If the device had been runtime-suspended before the system went into
* the sleep state it is going out of and it has never been resumed till
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antonio Ospite <[email protected]>
commit 61e2c70da9cfc79e8485eafa0f98b5919b04bbe1 upstream.
This id has been seen in the DSDT of the Teclast X98 Air 3G tablet based
on Intel Bay Trail.
Signed-off-by: Antonio Ospite <[email protected]>
Cc: Bastien Nocera <[email protected]>
Reviewed-by: Daniel Baluta <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/iio/accel/kxcjk-1013.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -1422,6 +1422,7 @@ static const struct dev_pm_ops kxcjk1013
static const struct acpi_device_id kx_acpi_match[] = {
{"KXCJ1013", KXCJK1013},
{"KXCJ1008", KXCJ91008},
+ {"KXCJ9000", KXCJ91008},
{"KXTJ1009", KXTJ21009},
{"SMO8500", KXCJ91008},
{ },
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 60df4642a83546fa6ea8286f5094ce8c0906c3ec upstream.
Make 3.81 doesn't have the 'undefine' command. Using undefine
to clear LDFLAGS fails when make version 3.81 is used. Fix it
to use override to clear LDFLAGS.
Tested-by: Shuah Khan <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Michael Ellerman <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Shuah Khan <[email protected]>
Cc: Sudip Mukherjee <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
tools/testing/selftests/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -26,7 +26,7 @@ TARGETS_HOTPLUG += memory-hotplug
# Makefile to avoid test build failures when test
# Makefile doesn't have explicit build rules.
ifeq (1,$(MAKELEVEL))
-undefine LDFLAGS
+override LDFLAGS =
override MAKEFLAGS =
endif
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <[email protected]>
commit 2576c28e3f623ed401db7e6197241865328620ef upstream.
- arch_spin_lock/unlock were lacking the ACQUIRE/RELEASE barriers
Since ARCv2 only provides load/load, store/store and all/all, we need
the full barrier
- LLOCK/SCOND based atomics, bitops, cmpxchg, which return modified
values were lacking the explicit smp barriers.
- Non LLOCK/SCOND varaints don't need the explicit barriers since that
is implicity provided by the spin locks used to implement the
critical section (the spin lock barriers in turn are also fixed in
this commit as explained above
Cc: Paul E. McKenney <[email protected]>
Acked-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arc/include/asm/atomic.h | 21 +++++++++++++++++++++
arch/arc/include/asm/bitops.h | 19 +++++++++++++++++++
arch/arc/include/asm/cmpxchg.h | 17 +++++++++++++++++
arch/arc/include/asm/spinlock.h | 32 ++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+)
--- a/arch/arc/include/asm/atomic.h
+++ b/arch/arc/include/asm/atomic.h
@@ -43,6 +43,12 @@ static inline int atomic_##op##_return(i
{ \
unsigned int temp; \
\
+ /* \
+ * Explicit full memory barrier needed before/after as \
+ * LLOCK/SCOND thmeselves don't provide any such semantics \
+ */ \
+ smp_mb(); \
+ \
__asm__ __volatile__( \
"1: llock %0, [%1] \n" \
" " #asm_op " %0, %0, %2 \n" \
@@ -52,6 +58,8 @@ static inline int atomic_##op##_return(i
: "r"(&v->counter), "ir"(i) \
: "cc"); \
\
+ smp_mb(); \
+ \
return temp; \
}
@@ -105,6 +113,9 @@ static inline int atomic_##op##_return(i
unsigned long flags; \
unsigned long temp; \
\
+ /* \
+ * spin lock/unlock provides the needed smp_mb() before/after \
+ */ \
atomic_ops_lock(flags); \
temp = v->counter; \
temp c_op i; \
@@ -142,9 +153,19 @@ ATOMIC_OP(and, &=, and)
#define __atomic_add_unless(v, a, u) \
({ \
int c, old; \
+ \
+ /* \
+ * Explicit full memory barrier needed before/after as \
+ * LLOCK/SCOND thmeselves don't provide any such semantics \
+ */ \
+ smp_mb(); \
+ \
c = atomic_read(v); \
while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c)\
c = old; \
+ \
+ smp_mb(); \
+ \
c; \
})
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -103,6 +103,12 @@ static inline int test_and_set_bit(unsig
if (__builtin_constant_p(nr))
nr &= 0x1f;
+ /*
+ * Explicit full memory barrier needed before/after as
+ * LLOCK/SCOND themselves don't provide any such semantics
+ */
+ smp_mb();
+
__asm__ __volatile__(
"1: llock %0, [%2] \n"
" bset %1, %0, %3 \n"
@@ -112,6 +118,8 @@ static inline int test_and_set_bit(unsig
: "r"(m), "ir"(nr)
: "cc");
+ smp_mb();
+
return (old & (1 << nr)) != 0;
}
@@ -125,6 +133,8 @@ test_and_clear_bit(unsigned long nr, vol
if (__builtin_constant_p(nr))
nr &= 0x1f;
+ smp_mb();
+
__asm__ __volatile__(
"1: llock %0, [%2] \n"
" bclr %1, %0, %3 \n"
@@ -134,6 +144,8 @@ test_and_clear_bit(unsigned long nr, vol
: "r"(m), "ir"(nr)
: "cc");
+ smp_mb();
+
return (old & (1 << nr)) != 0;
}
@@ -147,6 +159,8 @@ test_and_change_bit(unsigned long nr, vo
if (__builtin_constant_p(nr))
nr &= 0x1f;
+ smp_mb();
+
__asm__ __volatile__(
"1: llock %0, [%2] \n"
" bxor %1, %0, %3 \n"
@@ -156,6 +170,8 @@ test_and_change_bit(unsigned long nr, vo
: "r"(m), "ir"(nr)
: "cc");
+ smp_mb();
+
return (old & (1 << nr)) != 0;
}
@@ -235,6 +251,9 @@ static inline int test_and_set_bit(unsig
if (__builtin_constant_p(nr))
nr &= 0x1f;
+ /*
+ * spin lock/unlock provide the needed smp_mb() before/after
+ */
bitops_lock(flags);
old = *m;
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -10,6 +10,8 @@
#define __ASM_ARC_CMPXCHG_H
#include <linux/types.h>
+
+#include <asm/barrier.h>
#include <asm/smp.h>
#ifdef CONFIG_ARC_HAS_LLSC
@@ -19,6 +21,12 @@ __cmpxchg(volatile void *ptr, unsigned l
{
unsigned long prev;
+ /*
+ * Explicit full memory barrier needed before/after as
+ * LLOCK/SCOND thmeselves don't provide any such semantics
+ */
+ smp_mb();
+
__asm__ __volatile__(
"1: llock %0, [%1] \n"
" brne %0, %2, 2f \n"
@@ -30,6 +38,8 @@ __cmpxchg(volatile void *ptr, unsigned l
"r"(new) /* can't be "ir". scond can't take limm for "b" */
: "cc");
+ smp_mb();
+
return prev;
}
@@ -42,6 +52,9 @@ __cmpxchg(volatile void *ptr, unsigned l
int prev;
volatile unsigned long *p = ptr;
+ /*
+ * spin lock/unlock provide the needed smp_mb() before/after
+ */
atomic_ops_lock(flags);
prev = *p;
if (prev == expected)
@@ -77,12 +90,16 @@ static inline unsigned long __xchg(unsig
switch (size) {
case 4:
+ smp_mb();
+
__asm__ __volatile__(
" ex %0, [%1] \n"
: "+r"(val)
: "r"(ptr)
: "memory");
+ smp_mb();
+
return val;
}
return __xchg_bad_pointer();
--- a/arch/arc/include/asm/spinlock.h
+++ b/arch/arc/include/asm/spinlock.h
@@ -22,24 +22,46 @@ static inline void arch_spin_lock(arch_s
{
unsigned int tmp = __ARCH_SPIN_LOCK_LOCKED__;
+ /*
+ * This smp_mb() is technically superfluous, we only need the one
+ * after the lock for providing the ACQUIRE semantics.
+ * However doing the "right" thing was regressing hackbench
+ * so keeping this, pending further investigation
+ */
+ smp_mb();
+
__asm__ __volatile__(
"1: ex %0, [%1] \n"
" breq %0, %2, 1b \n"
: "+&r" (tmp)
: "r"(&(lock->slock)), "ir"(__ARCH_SPIN_LOCK_LOCKED__)
: "memory");
+
+ /*
+ * ACQUIRE barrier to ensure load/store after taking the lock
+ * don't "bleed-up" out of the critical section (leak-in is allowed)
+ * http://www.spinics.net/lists/kernel/msg2010409.html
+ *
+ * ARCv2 only has load-load, store-store and all-all barrier
+ * thus need the full all-all barrier
+ */
+ smp_mb();
}
static inline int arch_spin_trylock(arch_spinlock_t *lock)
{
unsigned int tmp = __ARCH_SPIN_LOCK_LOCKED__;
+ smp_mb();
+
__asm__ __volatile__(
"1: ex %0, [%1] \n"
: "+r" (tmp)
: "r"(&(lock->slock))
: "memory");
+ smp_mb();
+
return (tmp == __ARCH_SPIN_LOCK_UNLOCKED__);
}
@@ -47,12 +69,22 @@ static inline void arch_spin_unlock(arch
{
unsigned int tmp = __ARCH_SPIN_LOCK_UNLOCKED__;
+ /*
+ * RELEASE barrier: given the instructions avail on ARCv2, full barrier
+ * is the only option
+ */
+ smp_mb();
+
__asm__ __volatile__(
" ex %0, [%1] \n"
: "+r" (tmp)
: "r"(&(lock->slock))
: "memory");
+ /*
+ * superfluous, but keeping for now - see pairing version in
+ * arch_spin_lock above
+ */
smp_mb();
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineet Gupta <[email protected]>
commit d57f727264f1425a94689bafc7e99e502cb135b5 upstream.
When auditing cmpxchg call sites, Chuck noted that gcc was optimizing
away some of the desired LDs.
| do {
| new = old = *ipi_data_ptr;
| new |= 1U << msg;
| } while (cmpxchg(ipi_data_ptr, old, new) != old);
was generating to below
| 8015cef8: ld r2,[r4,0] <-- First LD
| 8015cefc: bset r1,r2,r1
|
| 8015cf00: llock r3,[r4] <-- atomic op
| 8015cf04: brne r3,r2,8015cf10
| 8015cf08: scond r1,[r4]
| 8015cf0c: bnz 8015cf00
|
| 8015cf10: brne r3,r2,8015cf00 <-- Branch doesn't go to orig LD
Although this was fixed by adding a ACCESS_ONCE in this call site, it
seems safer (for now at least) to add compiler barrier to LLSC based
cmpxchg
Reported-by: Chuck Jordan <[email protected]>
Acked-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Vineet Gupta <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arc/include/asm/cmpxchg.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
--- a/arch/arc/include/asm/cmpxchg.h
+++ b/arch/arc/include/asm/cmpxchg.h
@@ -33,10 +33,11 @@ __cmpxchg(volatile void *ptr, unsigned l
" scond %3, [%1] \n"
" bnz 1b \n"
"2: \n"
- : "=&r"(prev)
- : "r"(ptr), "ir"(expected),
- "r"(new) /* can't be "ir". scond can't take limm for "b" */
- : "cc");
+ : "=&r"(prev) /* Early clobber, to prevent reg reuse */
+ : "r"(ptr), /* Not "m": llock only supports reg direct addr mode */
+ "ir"(expected),
+ "r"(new) /* can't be "ir". scond can't take LIMM for "b" */
+ : "cc", "memory"); /* so that gcc knows memory is being written here */
smp_mb();
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Usyskin <[email protected]>
commit 3dc196eae1db548f05e53e5875ff87b8ff79f249 upstream.
Fix the hbm power gating state machine so it will wait till it receives
confirmation interrupt for the PG_ISOLATION_EXIT message.
In process of the suspend flow the devices first have to exit from the
power gating state (runtime pm resume).
If we do not handle the confirmation interrupt after sending
PG_ISOLATION_EXIT message, we may receive it already after the suspend
flow has changed the device state and interrupt will be interpreted as a
spurious event, consequently link reset will be invoked which will
prevent the device from completing the suspend flow
kernel: [6603] mei_reset:136: mei_me 0000:00:16.0: powering down: end of reset
kernel: [476] mei_me_irq_thread_handler:643: mei_me 0000:00:16.0: function called after ISR to handle the interrupt processing.
kernel: mei_me 0000:00:16.0: FW not ready: resetting
Cc: Gabriele Mazzotta <[email protected]>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=86241
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=770397
Tested-by: Gabriele Mazzotta <[email protected]>
Signed-off-by: Alexander Usyskin <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/misc/mei/client.c | 2 -
drivers/misc/mei/hw-me.c | 59 +++++++++++++++++++++++++++++++++++++++++----
drivers/misc/mei/hw-txe.c | 13 +++++++++
drivers/misc/mei/mei_dev.h | 11 ++++++++
4 files changed, 80 insertions(+), 5 deletions(-)
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -573,7 +573,7 @@ void mei_host_client_init(struct work_st
bool mei_hbuf_acquire(struct mei_device *dev)
{
if (mei_pg_state(dev) == MEI_PG_ON ||
- dev->pg_event == MEI_PG_EVENT_WAIT) {
+ mei_pg_in_transition(dev)) {
dev_dbg(dev->dev, "device is in pg\n");
return false;
}
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -629,11 +629,27 @@ int mei_me_pg_unset_sync(struct mei_devi
mutex_lock(&dev->device_lock);
reply:
- if (dev->pg_event == MEI_PG_EVENT_RECEIVED)
- ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_EXIT_RES_CMD);
+ if (dev->pg_event != MEI_PG_EVENT_RECEIVED) {
+ ret = -ETIME;
+ goto out;
+ }
+
+ dev->pg_event = MEI_PG_EVENT_INTR_WAIT;
+ ret = mei_hbm_pg(dev, MEI_PG_ISOLATION_EXIT_RES_CMD);
+ if (ret)
+ return ret;
+
+ mutex_unlock(&dev->device_lock);
+ wait_event_timeout(dev->wait_pg,
+ dev->pg_event == MEI_PG_EVENT_INTR_RECEIVED, timeout);
+ mutex_lock(&dev->device_lock);
+
+ if (dev->pg_event == MEI_PG_EVENT_INTR_RECEIVED)
+ ret = 0;
else
ret = -ETIME;
+out:
dev->pg_event = MEI_PG_EVENT_IDLE;
hw->pg_state = MEI_PG_OFF;
@@ -641,6 +657,19 @@ reply:
}
/**
+ * mei_me_pg_in_transition - is device now in pg transition
+ *
+ * @dev: the device structure
+ *
+ * Return: true if in pg transition, false otherwise
+ */
+static bool mei_me_pg_in_transition(struct mei_device *dev)
+{
+ return dev->pg_event >= MEI_PG_EVENT_WAIT &&
+ dev->pg_event <= MEI_PG_EVENT_INTR_WAIT;
+}
+
+/**
* mei_me_pg_is_enabled - detect if PG is supported by HW
*
* @dev: the device structure
@@ -672,6 +701,24 @@ notsupported:
}
/**
+ * mei_me_pg_intr - perform pg processing in interrupt thread handler
+ *
+ * @dev: the device structure
+ */
+static void mei_me_pg_intr(struct mei_device *dev)
+{
+ struct mei_me_hw *hw = to_me_hw(dev);
+
+ if (dev->pg_event != MEI_PG_EVENT_INTR_WAIT)
+ return;
+
+ dev->pg_event = MEI_PG_EVENT_INTR_RECEIVED;
+ hw->pg_state = MEI_PG_OFF;
+ if (waitqueue_active(&dev->wait_pg))
+ wake_up(&dev->wait_pg);
+}
+
+/**
* mei_me_irq_quick_handler - The ISR of the MEI device
*
* @irq: The irq number
@@ -729,6 +776,8 @@ irqreturn_t mei_me_irq_thread_handler(in
goto end;
}
+ mei_me_pg_intr(dev);
+
/* check if we need to start the dev */
if (!mei_host_is_ready(dev)) {
if (mei_hw_is_ready(dev)) {
@@ -765,9 +814,10 @@ irqreturn_t mei_me_irq_thread_handler(in
/*
* During PG handshake only allowed write is the replay to the
* PG exit message, so block calling write function
- * if the pg state is not idle
+ * if the pg event is in PG handshake
*/
- if (dev->pg_event == MEI_PG_EVENT_IDLE) {
+ if (dev->pg_event != MEI_PG_EVENT_WAIT &&
+ dev->pg_event != MEI_PG_EVENT_RECEIVED) {
rets = mei_irq_write_handler(dev, &complete_list);
dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
}
@@ -792,6 +842,7 @@ static const struct mei_hw_ops mei_me_hw
.hw_config = mei_me_hw_config,
.hw_start = mei_me_hw_start,
+ .pg_in_transition = mei_me_pg_in_transition,
.pg_is_enabled = mei_me_pg_is_enabled,
.intr_clear = mei_me_intr_clear,
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -302,6 +302,18 @@ int mei_txe_aliveness_set_sync(struct me
}
/**
+ * mei_txe_pg_in_transition - is device now in pg transition
+ *
+ * @dev: the device structure
+ *
+ * Return: true if in pg transition, false otherwise
+ */
+static bool mei_txe_pg_in_transition(struct mei_device *dev)
+{
+ return dev->pg_event == MEI_PG_EVENT_WAIT;
+}
+
+/**
* mei_txe_pg_is_enabled - detect if PG is supported by HW
*
* @dev: the device structure
@@ -1138,6 +1150,7 @@ static const struct mei_hw_ops mei_txe_h
.hw_config = mei_txe_hw_config,
.hw_start = mei_txe_hw_start,
+ .pg_in_transition = mei_txe_pg_in_transition,
.pg_is_enabled = mei_txe_pg_is_enabled,
.intr_clear = mei_txe_intr_clear,
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -269,6 +269,7 @@ struct mei_cl {
* @fw_status : get fw status registers
* @pg_state : power gating state of the device
+ * @pg_in_transition : is device now in pg transition
* @pg_is_enabled : is power gating enabled
* @intr_clear : clear pending interrupts
@@ -298,6 +299,7 @@ struct mei_hw_ops {
int (*fw_status)(struct mei_device *dev, struct mei_fw_status *fw_sts);
enum mei_pg_state (*pg_state)(struct mei_device *dev);
+ bool (*pg_in_transition)(struct mei_device *dev);
bool (*pg_is_enabled)(struct mei_device *dev);
void (*intr_clear)(struct mei_device *dev);
@@ -396,11 +398,15 @@ struct mei_cl_device {
* @MEI_PG_EVENT_IDLE: the driver is not in power gating transition
* @MEI_PG_EVENT_WAIT: the driver is waiting for a pg event to complete
* @MEI_PG_EVENT_RECEIVED: the driver received pg event
+ * @MEI_PG_EVENT_INTR_WAIT: the driver is waiting for a pg event interrupt
+ * @MEI_PG_EVENT_INTR_RECEIVED: the driver received pg event interrupt
*/
enum mei_pg_event {
MEI_PG_EVENT_IDLE,
MEI_PG_EVENT_WAIT,
MEI_PG_EVENT_RECEIVED,
+ MEI_PG_EVENT_INTR_WAIT,
+ MEI_PG_EVENT_INTR_RECEIVED,
};
/**
@@ -727,6 +733,11 @@ static inline enum mei_pg_state mei_pg_s
return dev->ops->pg_state(dev);
}
+static inline bool mei_pg_in_transition(struct mei_device *dev)
+{
+ return dev->ops->pg_in_transition(dev);
+}
+
static inline bool mei_pg_is_enabled(struct mei_device *dev)
{
return dev->ops->pg_is_enabled(dev);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Winkler <[email protected]>
commit fe292283c23329218e384bffc6cb4bfa3fd92277 upstream.
HW has to be in known state before the initialisation
sequence is started. The polling step for settling aliveness
was set to 200ms while in practise this can be done in up to 30msecs.
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Barak Yoresh <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/misc/mei/hw-txe.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -16,6 +16,7 @@
#include <linux/pci.h>
#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/irqreturn.h>
@@ -218,26 +219,25 @@ static u32 mei_txe_aliveness_get(struct
*
* Polls for HICR_HOST_ALIVENESS_RESP.ALIVENESS_RESP to be set
*
- * Return: > 0 if the expected value was received, -ETIME otherwise
+ * Return: 0 if the expected value was received, -ETIME otherwise
*/
static int mei_txe_aliveness_poll(struct mei_device *dev, u32 expected)
{
struct mei_txe_hw *hw = to_txe_hw(dev);
- int t = 0;
+ ktime_t stop, start;
+ start = ktime_get();
+ stop = ktime_add(start, ms_to_ktime(SEC_ALIVENESS_WAIT_TIMEOUT));
do {
hw->aliveness = mei_txe_aliveness_get(dev);
if (hw->aliveness == expected) {
dev->pg_event = MEI_PG_EVENT_IDLE;
- dev_dbg(dev->dev,
- "aliveness settled after %d msecs\n", t);
- return t;
+ dev_dbg(dev->dev, "aliveness settled after %lld usecs\n",
+ ktime_to_us(ktime_sub(ktime_get(), start)));
+ return 0;
}
- mutex_unlock(&dev->device_lock);
- msleep(MSEC_PER_SEC / 5);
- mutex_lock(&dev->device_lock);
- t += MSEC_PER_SEC / 5;
- } while (t < SEC_ALIVENESS_WAIT_TIMEOUT);
+ usleep_range(20, 50);
+ } while (ktime_before(ktime_get(), stop));
dev->pg_event = MEI_PG_EVENT_IDLE;
dev_err(dev->dev, "aliveness timed out\n");
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit 565630d503ef24e44c252bed55571b3a0d68455f upstream.
After secondary CPU boot or hotplug, the active_mm of the idle thread is
&init_mm. The init_mm.pgd (swapper_pg_dir) is only meant for TTBR1_EL1
and must not be set in TTBR0_EL1. Since when active_mm == &init_mm the
TTBR0_EL1 is already set to the reserved value, there is no need to
perform any context reset.
Signed-off-by: Catalin Marinas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arm64/mm/context.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -92,6 +92,14 @@ static void reset_context(void *info)
unsigned int cpu = smp_processor_id();
struct mm_struct *mm = current->active_mm;
+ /*
+ * current->active_mm could be init_mm for the idle thread immediately
+ * after secondary CPU boot or hotplug. TTBR0_EL1 is already set to
+ * the reserved value, so no need to reset any context.
+ */
+ if (mm == &init_mm)
+ return;
+
smp_rmb();
asid = cpu_last_asid + cpu;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit 46b0567c851cf85d6ba6f23eef385ec9111d09bc upstream.
Commit 6c81fe7925cc4c42 ("arm64: enable context tracking") did not
update el0_sp_pc to use ct_user_exit, but this appears to have been
unintentional. In commit 6ab6463aeb5fbc75 ("arm64: adjust el0_sync so
that a function can be called") we made x0 available, and in the return
to userspace we call ct_user_enter in the kernel_exit macro.
Due to this, we currently don't correctly inform RCU of the user->kernel
transition, and may erroneously account for time spent in the kernel as
if we were in an extended quiescent state when CONFIG_CONTEXT_TRACKING
is enabled.
As we do record the kernel->user transition, a userspace application
making accesses from an unaligned stack pointer can demonstrate the
imbalance, provoking the following warning:
------------[ cut here ]------------
WARNING: CPU: 2 PID: 3660 at kernel/context_tracking.c:75 context_tracking_enter+0xd8/0xe4()
Modules linked in:
CPU: 2 PID: 3660 Comm: a.out Not tainted 4.1.0-rc7+ #8
Hardware name: ARM Juno development board (r0) (DT)
Call trace:
[<ffffffc000089914>] dump_backtrace+0x0/0x124
[<ffffffc000089a48>] show_stack+0x10/0x1c
[<ffffffc0005b3cbc>] dump_stack+0x84/0xc8
[<ffffffc0000b3214>] warn_slowpath_common+0x98/0xd0
[<ffffffc0000b330c>] warn_slowpath_null+0x14/0x20
[<ffffffc00013ada4>] context_tracking_enter+0xd4/0xe4
[<ffffffc0005b534c>] preempt_schedule_irq+0xd4/0x114
[<ffffffc00008561c>] el1_preempt+0x4/0x28
[<ffffffc0001b8040>] exit_files+0x38/0x4c
[<ffffffc0000b5b94>] do_exit+0x430/0x978
[<ffffffc0000b614c>] do_group_exit+0x40/0xd4
[<ffffffc0000c0208>] get_signal+0x23c/0x4f4
[<ffffffc0000890b4>] do_signal+0x1ac/0x518
[<ffffffc000089650>] do_notify_resume+0x5c/0x68
---[ end trace 963c192600337066 ]---
This patch adds the missing ct_user_exit to the el0_sp_pc entry path,
correcting the context tracking for this case.
Signed-off-by: Mark Rutland <[email protected]>
Acked-by: Will Deacon <[email protected]>
Fixes: 6c81fe7925cc ("arm64: enable context tracking")
Signed-off-by: Catalin Marinas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arm64/kernel/entry.S | 1 +
1 file changed, 1 insertion(+)
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -517,6 +517,7 @@ el0_sp_pc:
mrs x26, far_el1
// enable interrupts before calling the main handler
enable_dbg_and_irq
+ ct_user_exit
mov x0, x26
mov x1, x25
mov x2, sp
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave P Martin <[email protected]>
commit b9bcc919931611498e856eae9bf66337330d04cc upstream.
The memmap freeing code in free_unused_memmap() computes the end of
each memblock by adding the memblock size onto the base. However,
if SPARSEMEM is enabled then the value (start) used for the base
may already have been rounded downwards to work out which memmap
entries to free after the previous memblock.
This may cause memmap entries that are in use to get freed.
In general, you're not likely to hit this problem unless there
are at least 2 memblocks and one of them is not aligned to a
sparsemem section boundary. Note that carve-outs can increase
the number of memblocks by splitting the regions listed in the
device tree.
This problem doesn't occur with SPARSEMEM_VMEMMAP, because the
vmemmap code deals with freeing the unused regions of the memmap
instead of requiring the arch code to do it.
This patch gets the memblock base out of the memblock directly when
computing the block end address to ensure the correct value is used.
Signed-off-by: Dave Martin <[email protected]>
Signed-off-by: Catalin Marinas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arm64/mm/init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -260,7 +260,7 @@ static void __init free_unused_memmap(vo
* memmap entries are valid from the bank end aligned to
* MAX_ORDER_NR_PAGES.
*/
- prev_end = ALIGN(start + __phys_to_pfn(reg->size),
+ prev_end = ALIGN(__phys_to_pfn(reg->base + reg->size),
MAX_ORDER_NR_PAGES);
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Will Deacon <[email protected]>
commit 6f1a6ae87c0c60d7c462ef8fd071f291aa7a9abb upstream.
When building the kernel with a bare-metal (ELF) toolchain, the -shared
option may not be passed down to collect2, resulting in silent corruption
of the vDSO image (in particular, the DYNAMIC section is omitted).
The effect of this corruption is that the dynamic linker fails to find
the vDSO symbols and libc is instead used for the syscalls that we
intended to optimise (e.g. gettimeofday). Functionally, there is no
issue as the sigreturn trampoline is still intact and located by the
kernel.
This patch fixes the problem by explicitly passing -shared to the linker
when building the vDSO.
Reported-by: Szabolcs Nagy <[email protected]>
Reported-by: James Greenlaigh <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
Signed-off-by: Catalin Marinas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/arm64/kernel/vdso/Makefile | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -15,6 +15,10 @@ ccflags-y := -shared -fno-common -fno-bu
ccflags-y += -nostdlib -Wl,-soname=linux-vdso.so.1 \
$(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+# Workaround for bare-metal (ELF) toolchains that neglect to pass -shared
+# down to collect2, resulting in silent corruption of the vDSO image.
+ccflags-y += -Wl,-shared
+
obj-y += vdso.o
extra-y += vdso.lds vdso-offsets.h
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Catalin Marinas <[email protected]>
commit c5f3b1a51a591c18c8b33983908e7fdda6ae417e upstream.
The kmemleak scanning thread can run for minutes. Callbacks like
kmemleak_free() are allowed during this time, the race being taken care
of by the object->lock spinlock. Such lock also prevents a memory block
from being freed or unmapped while it is being scanned by blocking the
kmemleak_free() -> ... -> __delete_object() function until the lock is
released in scan_object().
When a kmemleak error occurs (e.g. it fails to allocate its metadata),
kmemleak_enabled is set and __delete_object() is no longer called on
freed objects. If kmemleak_scan is running at the same time,
kmemleak_free() no longer waits for the object scanning to complete,
allowing the corresponding memory block to be freed or unmapped (in the
case of vfree()). This leads to kmemleak_scan potentially triggering a
page fault.
This patch separates the kmemleak_free() enabling/disabling from the
overall kmemleak_enabled nob so that we can defer the disabling of the
object freeing tracking until the scanning thread completed. The
kmemleak_free_part() is deliberately ignored by this patch since this is
only called during boot before the scanning thread started.
Signed-off-by: Catalin Marinas <[email protected]>
Reported-by: Vignesh Radhakrishnan <[email protected]>
Tested-by: Vignesh Radhakrishnan <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
mm/kmemleak.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -195,6 +195,8 @@ static struct kmem_cache *scan_area_cach
/* set if tracing memory operations is enabled */
static int kmemleak_enabled;
+/* same as above but only for the kmemleak_free() callback */
+static int kmemleak_free_enabled;
/* set in the late_initcall if there were no errors */
static int kmemleak_initialized;
/* enables or disables early logging of the memory operations */
@@ -942,7 +944,7 @@ void __ref kmemleak_free(const void *ptr
{
pr_debug("%s(0x%p)\n", __func__, ptr);
- if (kmemleak_enabled && ptr && !IS_ERR(ptr))
+ if (kmemleak_free_enabled && ptr && !IS_ERR(ptr))
delete_object_full((unsigned long)ptr);
else if (kmemleak_early_log)
log_early(KMEMLEAK_FREE, ptr, 0, 0);
@@ -982,7 +984,7 @@ void __ref kmemleak_free_percpu(const vo
pr_debug("%s(0x%p)\n", __func__, ptr);
- if (kmemleak_enabled && ptr && !IS_ERR(ptr))
+ if (kmemleak_free_enabled && ptr && !IS_ERR(ptr))
for_each_possible_cpu(cpu)
delete_object_full((unsigned long)per_cpu_ptr(ptr,
cpu));
@@ -1750,6 +1752,13 @@ static void kmemleak_do_cleanup(struct w
mutex_lock(&scan_mutex);
stop_scan_thread();
+ /*
+ * Once the scan thread has stopped, it is safe to no longer track
+ * object freeing. Ordering of the scan thread stopping and the memory
+ * accesses below is guaranteed by the kthread_stop() function.
+ */
+ kmemleak_free_enabled = 0;
+
if (!kmemleak_found_leaks)
__kmemleak_do_cleanup();
else
@@ -1776,6 +1785,8 @@ static void kmemleak_disable(void)
/* check whether it is too early for a kernel thread */
if (kmemleak_initialized)
schedule_work(&cleanup_work);
+ else
+ kmemleak_free_enabled = 0;
pr_info("Kernel memory leak detector disabled\n");
}
@@ -1840,8 +1851,10 @@ void __init kmemleak_init(void)
if (kmemleak_error) {
local_irq_restore(flags);
return;
- } else
+ } else {
kmemleak_enabled = 1;
+ kmemleak_free_enabled = 1;
+ }
local_irq_restore(flags);
/*
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Larry Finger <[email protected]>
commit 8a8c35fadfaf55629a37ef1a8ead1b8fb32581d2 upstream.
Beginning at commit d52d3997f843 ("ipv6: Create percpu rt6_info"), the
following INFO splat is logged:
===============================
[ INFO: suspicious RCU usage. ]
4.1.0-rc7-next-20150612 #1 Not tainted
-------------------------------
kernel/sched/core.c:7318 Illegal context switch in RCU-bh read-side critical section!
other info that might help us debug this:
rcu_scheduler_active = 1, debug_locks = 0
3 locks held by systemd/1:
#0: (rtnl_mutex){+.+.+.}, at: [<ffffffff815f0c8f>] rtnetlink_rcv+0x1f/0x40
#1: (rcu_read_lock_bh){......}, at: [<ffffffff816a34e2>] ipv6_add_addr+0x62/0x540
#2: (addrconf_hash_lock){+...+.}, at: [<ffffffff816a3604>] ipv6_add_addr+0x184/0x540
stack backtrace:
CPU: 0 PID: 1 Comm: systemd Not tainted 4.1.0-rc7-next-20150612 #1
Hardware name: TOSHIBA TECRA A50-A/TECRA A50-A, BIOS Version 4.20 04/17/2014
Call Trace:
dump_stack+0x4c/0x6e
lockdep_rcu_suspicious+0xe7/0x120
___might_sleep+0x1d5/0x1f0
__might_sleep+0x4d/0x90
kmem_cache_alloc+0x47/0x250
create_object+0x39/0x2e0
kmemleak_alloc_percpu+0x61/0xe0
pcpu_alloc+0x370/0x630
Additional backtrace lines are truncated. In addition, the above splat
is followed by several "BUG: sleeping function called from invalid
context at mm/slub.c:1268" outputs. As suggested by Martin KaFai Lau,
these are the clue to the fix. Routine kmemleak_alloc_percpu() always
uses GFP_KERNEL for its allocations, whereas it should follow the gfp
from its callers.
Reviewed-by: Catalin Marinas <[email protected]>
Reviewed-by: Kamalesh Babulal <[email protected]>
Acked-by: Martin KaFai Lau <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Cc: Martin KaFai Lau <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Tejun Heo <[email protected]>
Cc: Christoph Lameter <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/kmemleak.h | 6 ++++--
mm/kmemleak.c | 9 +++++----
mm/percpu.c | 2 +-
3 files changed, 10 insertions(+), 7 deletions(-)
--- a/include/linux/kmemleak.h
+++ b/include/linux/kmemleak.h
@@ -28,7 +28,8 @@
extern void kmemleak_init(void) __ref;
extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
gfp_t gfp) __ref;
-extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) __ref;
+extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
+ gfp_t gfp) __ref;
extern void kmemleak_free(const void *ptr) __ref;
extern void kmemleak_free_part(const void *ptr, size_t size) __ref;
extern void kmemleak_free_percpu(const void __percpu *ptr) __ref;
@@ -71,7 +72,8 @@ static inline void kmemleak_alloc_recurs
gfp_t gfp)
{
}
-static inline void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size)
+static inline void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
+ gfp_t gfp)
{
}
static inline void kmemleak_free(const void *ptr)
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -909,12 +909,13 @@ EXPORT_SYMBOL_GPL(kmemleak_alloc);
* kmemleak_alloc_percpu - register a newly allocated __percpu object
* @ptr: __percpu pointer to beginning of the object
* @size: size of the object
+ * @gfp: flags used for kmemleak internal memory allocations
*
* This function is called from the kernel percpu allocator when a new object
- * (memory block) is allocated (alloc_percpu). It assumes GFP_KERNEL
- * allocation.
+ * (memory block) is allocated (alloc_percpu).
*/
-void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size)
+void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
+ gfp_t gfp)
{
unsigned int cpu;
@@ -927,7 +928,7 @@ void __ref kmemleak_alloc_percpu(const v
if (kmemleak_enabled && ptr && !IS_ERR(ptr))
for_each_possible_cpu(cpu)
create_object((unsigned long)per_cpu_ptr(ptr, cpu),
- size, 0, GFP_KERNEL);
+ size, 0, gfp);
else if (kmemleak_early_log)
log_early(KMEMLEAK_ALLOC_PERCPU, ptr, size, 0);
}
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1030,7 +1030,7 @@ area_found:
memset((void *)pcpu_chunk_addr(chunk, cpu, 0) + off, 0, size);
ptr = __addr_to_pcpu_ptr(chunk->base_addr + off);
- kmemleak_alloc_percpu(ptr, size);
+ kmemleak_alloc_percpu(ptr, size, gfp);
return ptr;
fail_unlock:
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka <[email protected]>
commit 0867a57c4f80a566dda1bac975b42fcd857cb489 upstream.
Since commit 077fcf116c8c ("mm/thp: allocate transparent hugepages on
local node"), we handle THP allocations on page fault in a special way -
for non-interleave memory policies, the allocation is only attempted on
the node local to the current CPU, if the policy's nodemask allows the
node.
This is motivated by the assumption that THP benefits cannot offset the
cost of remote accesses, so it's better to fallback to base pages on the
local node (which might still be available, while huge pages are not due
to fragmentation) than to allocate huge pages on a remote node.
The nodemask check prevents us from violating e.g. MPOL_BIND policies
where the local node is not among the allowed nodes. However, the
current implementation can still give surprising results for the
MPOL_PREFERRED policy when the preferred node is different than the
current CPU's local node.
In such case we should honor the preferred node and not use the local
node, which is what this patch does. If hugepage allocation on the
preferred node fails, we fall back to base pages and don't try other
nodes, with the same motivation as is done for the local node hugepage
allocations. The patch also moves the MPOL_INTERLEAVE check around to
simplify the hugepage specific test.
The difference can be demonstrated using in-tree transhuge-stress test
on the following 2-node machine where half memory on one node was
occupied to show the difference.
> numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 24 25 26 27 28 29 30 31 32 33 34 35
node 0 size: 7878 MB
node 0 free: 3623 MB
node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23 36 37 38 39 40 41 42 43 44 45 46 47
node 1 size: 8045 MB
node 1 free: 7818 MB
node distances:
node 0 1
0: 10 21
1: 21 10
Before the patch:
> numactl -p0 -C0 ./transhuge-stress
transhuge-stress: 2.197 s/loop, 0.276 ms/page, 7249.168 MiB/s 7962 succeed, 0 failed, 1786 different pages
> numactl -p0 -C12 ./transhuge-stress
transhuge-stress: 2.962 s/loop, 0.372 ms/page, 5376.172 MiB/s 7962 succeed, 0 failed, 3873 different pages
Number of successful THP allocations corresponds to free memory on node 0 in
the first case and node 1 in the second case, i.e. -p parameter is ignored and
cpu binding "wins".
After the patch:
> numactl -p0 -C0 ./transhuge-stress
transhuge-stress: 2.183 s/loop, 0.274 ms/page, 7295.516 MiB/s 7962 succeed, 0 failed, 1760 different pages
> numactl -p0 -C12 ./transhuge-stress
transhuge-stress: 2.878 s/loop, 0.361 ms/page, 5533.638 MiB/s 7962 succeed, 0 failed, 1750 different pages
> numactl -p1 -C0 ./transhuge-stress
transhuge-stress: 4.628 s/loop, 0.581 ms/page, 3440.893 MiB/s 7962 succeed, 0 failed, 3918 different pages
The -p parameter is respected regardless of cpu binding.
> numactl -C0 ./transhuge-stress
transhuge-stress: 2.202 s/loop, 0.277 ms/page, 7230.003 MiB/s 7962 succeed, 0 failed, 1750 different pages
> numactl -C12 ./transhuge-stress
transhuge-stress: 3.020 s/loop, 0.379 ms/page, 5273.324 MiB/s 7962 succeed, 0 failed, 3916 different pages
Without -p parameter, hugepage restriction to CPU-local node works as before.
Fixes: 077fcf116c8c ("mm/thp: allocate transparent hugepages on local node")
Signed-off-by: Vlastimil Babka <[email protected]>
Cc: Aneesh Kumar K.V <[email protected]>
Acked-by: David Rientjes <[email protected]>
Cc: Kirill A. Shutemov <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Cc: Michal Hocko <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
mm/mempolicy.c | 38 ++++++++++++++++++++++----------------
1 file changed, 22 insertions(+), 16 deletions(-)
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1971,35 +1971,41 @@ retry_cpuset:
pol = get_vma_policy(vma, addr);
cpuset_mems_cookie = read_mems_allowed_begin();
- if (unlikely(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hugepage &&
- pol->mode != MPOL_INTERLEAVE)) {
+ if (pol->mode == MPOL_INTERLEAVE) {
+ unsigned nid;
+
+ nid = interleave_nid(pol, vma, addr, PAGE_SHIFT + order);
+ mpol_cond_put(pol);
+ page = alloc_page_interleave(gfp, order, nid);
+ goto out;
+ }
+
+ if (unlikely(IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && hugepage)) {
+ int hpage_node = node;
+
/*
* For hugepage allocation and non-interleave policy which
- * allows the current node, we only try to allocate from the
- * current node and don't fall back to other nodes, as the
- * cost of remote accesses would likely offset THP benefits.
+ * allows the current node (or other explicitly preferred
+ * node) we only try to allocate from the current/preferred
+ * node and don't fall back to other nodes, as the cost of
+ * remote accesses would likely offset THP benefits.
*
* If the policy is interleave, or does not allow the current
* node in its nodemask, we allocate the standard way.
*/
+ if (pol->mode == MPOL_PREFERRED &&
+ !(pol->flags & MPOL_F_LOCAL))
+ hpage_node = pol->v.preferred_node;
+
nmask = policy_nodemask(gfp, pol);
- if (!nmask || node_isset(node, *nmask)) {
+ if (!nmask || node_isset(hpage_node, *nmask)) {
mpol_cond_put(pol);
- page = alloc_pages_exact_node(node,
+ page = alloc_pages_exact_node(hpage_node,
gfp | __GFP_THISNODE, order);
goto out;
}
}
- if (pol->mode == MPOL_INTERLEAVE) {
- unsigned nid;
-
- nid = interleave_nid(pol, vma, addr, PAGE_SHIFT + order);
- mpol_cond_put(pol);
- page = alloc_page_interleave(gfp, order, nid);
- goto out;
- }
-
nmask = policy_nodemask(gfp, pol);
zl = policy_zonelist(gfp, pol, node);
mpol_cond_put(pol);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sagi Grimberg <[email protected]>
commit 2f1b6b7d9a815f341b18dfd26a363f37d4d3c96a upstream.
When receiving a new iser connect request we serialize
the pending requests by adding the newly created iser connection
to the np accept list and let the login thread process the connect
request one by one (np_accept_wait).
In case we received a disconnect request before the iser_conn
has begun processing (still linked in np_accept_list) we should
detach it from the list and clean it up and not have the login
thread process a stale connection. We do it only when the connection
state is not already terminating (initiator driven disconnect) as
this might lead us to access np_accept_mutex after the np was released
in live shutdown scenarios.
Signed-off-by: Sagi Grimberg <[email protected]>
Signed-off-by: Jenny Falkovich <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/ulp/isert/ib_isert.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -65,6 +65,8 @@ static int
isert_rdma_accept(struct isert_conn *isert_conn);
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
+static void isert_release_work(struct work_struct *work);
+
static inline bool
isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd)
{
@@ -604,6 +606,7 @@ isert_connect_request(struct rdma_cm_id
mutex_init(&isert_conn->conn_mutex);
spin_lock_init(&isert_conn->conn_lock);
INIT_LIST_HEAD(&isert_conn->conn_fr_pool);
+ INIT_WORK(&isert_conn->release_work, isert_release_work);
isert_conn->conn_cm_id = cma_id;
@@ -863,6 +866,7 @@ isert_disconnected_handler(struct rdma_c
{
struct isert_np *isert_np = cma_id->context;
struct isert_conn *isert_conn;
+ bool terminating = false;
if (isert_np->np_cm_id == cma_id)
return isert_np_cma_handler(cma_id->context, event);
@@ -870,12 +874,25 @@ isert_disconnected_handler(struct rdma_c
isert_conn = cma_id->qp->qp_context;
mutex_lock(&isert_conn->conn_mutex);
+ terminating = (isert_conn->state == ISER_CONN_TERMINATING);
isert_conn_terminate(isert_conn);
mutex_unlock(&isert_conn->conn_mutex);
isert_info("conn %p completing conn_wait\n", isert_conn);
complete(&isert_conn->conn_wait);
+ if (terminating)
+ goto out;
+
+ mutex_lock(&isert_np->np_accept_mutex);
+ if (!list_empty(&isert_conn->conn_accept_node)) {
+ list_del_init(&isert_conn->conn_accept_node);
+ isert_put_conn(isert_conn);
+ queue_work(isert_release_wq, &isert_conn->release_work);
+ }
+ mutex_unlock(&isert_np->np_accept_mutex);
+
+out:
return 0;
}
@@ -3305,7 +3322,6 @@ static void isert_wait_conn(struct iscsi
isert_wait4flush(isert_conn);
isert_wait4logout(isert_conn);
- INIT_WORK(&isert_conn->release_work, isert_release_work);
queue_work(isert_release_wq, &isert_conn->release_work);
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arun Chandran <[email protected]>
commit 15b8d2c41fe5839582029f65c5f7004db451cc2b upstream.
In big endian mode regmap_bulk_read gives incorrect data
for byte reads.
This is because memcpy of a single byte from an address
after full word read gives different results when
endianness differs. ie. we get little-end in LE and big-end in BE.
Signed-off-by: Arun Chandran <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/regmap/regmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2318,7 +2318,7 @@ int regmap_bulk_read(struct regmap *map,
&ival);
if (ret != 0)
return ret;
- memcpy(val + (i * val_bytes), &ival, val_bytes);
+ map->format.format_val(val + (i * val_bytes), ival, 0);
}
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxime Coquelin <[email protected]>
commit 921cc29473a0d7c109105c1876ddb432f4a4be7d upstream.
The way the mask is generated in regmap_field_init() is wrong.
Indeed, a field initialized with msb = 31 and lsb = 0 provokes a shift
overflow while calculating the mask field.
On some 32 bits architectures, such as x86, the generated mask is 0,
instead of the expected 0xffffffff.
This patch uses GENMASK() to fix the problem, as this macro is already safe
regarding shift overflow.
Signed-off-by: Maxime Coquelin <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/base/regmap/regmap.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -945,11 +945,10 @@ EXPORT_SYMBOL_GPL(devm_regmap_init);
static void regmap_field_init(struct regmap_field *rm_field,
struct regmap *regmap, struct reg_field reg_field)
{
- int field_bits = reg_field.msb - reg_field.lsb + 1;
rm_field->regmap = regmap;
rm_field->reg = reg_field.reg;
rm_field->shift = reg_field.lsb;
- rm_field->mask = ((BIT(field_bits) - 1) << reg_field.lsb);
+ rm_field->mask = GENMASK(reg_field.msb, reg_field.lsb);
rm_field->id_size = reg_field.id_size;
rm_field->id_offset = reg_field.id_offset;
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Perches <[email protected]>
commit c53403a37cf083ce85da720f18918f73580d0064 upstream.
The code should handle more than 32 bits here because "id"
can be a value up to MAX77686_REGULATORS (currently 34).
Convert the gpio_enabled type to DECLARE_BITMAP and use
test_bit/set_bit.
Fixes: 3307e9025d29 ("regulator: max77686: Add GPIO control")
Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Joe Perches <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/regulator/max77686.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/regulator/max77686.c
+++ b/drivers/regulator/max77686.c
@@ -88,7 +88,7 @@ enum max77686_ramp_rate {
};
struct max77686_data {
- u64 gpio_enabled:MAX77686_REGULATORS;
+ DECLARE_BITMAP(gpio_enabled, MAX77686_REGULATORS);
/* Array indexed by regulator id */
unsigned int opmode[MAX77686_REGULATORS];
@@ -121,7 +121,7 @@ static unsigned int max77686_map_normal_
case MAX77686_BUCK8:
case MAX77686_BUCK9:
case MAX77686_LDO20 ... MAX77686_LDO22:
- if (max77686->gpio_enabled & (1 << id))
+ if (test_bit(id, max77686->gpio_enabled))
return MAX77686_GPIO_CONTROL;
}
@@ -277,7 +277,7 @@ static int max77686_of_parse_cb(struct d
}
if (gpio_is_valid(config->ena_gpio)) {
- max77686->gpio_enabled |= (1 << desc->id);
+ set_bit(desc->id, max77686->gpio_enabled);
return regmap_update_bits(config->regmap, desc->enable_reg,
desc->enable_mask,
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
commit a7068e3932eee8268c4ce4e080a338ee7b8a27bf upstream.
The buffer for condtraints debug isn't big enough to hold the output
in all cases. So fix this issue by increasing the buffer.
Signed-off-by: Stefan Wahren <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/regulator/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -770,7 +770,7 @@ static int suspend_prepare(struct regula
static void print_constraints(struct regulator_dev *rdev)
{
struct regulation_constraints *constraints = rdev->constraints;
- char buf[80] = "";
+ char buf[160] = "";
int count = 0;
int ret;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miroslav Benes <[email protected]>
commit 9a1bd63cdae4b623494c4ebaf723a91c35ec49fb upstream.
The list of loaded modules is walked through in
module_kallsyms_on_each_symbol (called by kallsyms_on_each_symbol). The
module_mutex lock should be acquired to prevent potential corruptions
in the list.
This was uncovered with new lockdep asserts in module code introduced by
the commit 0be964be0d45 ("module: Sanitize RCU usage and locking") in
recent next- trees.
Signed-off-by: Miroslav Benes <[email protected]>
Acked-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/livepatch/core.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
--- a/kernel/livepatch/core.c
+++ b/kernel/livepatch/core.c
@@ -179,7 +179,9 @@ static int klp_find_object_symbol(const
.count = 0
};
+ mutex_lock(&module_mutex);
kallsyms_on_each_symbol(klp_find_callback, &args);
+ mutex_unlock(&module_mutex);
if (args.count == 0)
pr_err("symbol '%s' not found in symbol table\n", name);
@@ -219,13 +221,19 @@ static int klp_verify_vmlinux_symbol(con
.name = name,
.addr = addr,
};
+ int ret;
- if (kallsyms_on_each_symbol(klp_verify_callback, &args))
- return 0;
+ mutex_lock(&module_mutex);
+ ret = kallsyms_on_each_symbol(klp_verify_callback, &args);
+ mutex_unlock(&module_mutex);
+
+ if (!ret) {
+ pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n",
+ name, addr);
+ return -EINVAL;
+ }
- pr_err("symbol '%s' not found at specified address 0x%016lx, kernel mismatch?\n",
- name, addr);
- return -EINVAL;
+ return 0;
}
static int klp_find_verify_func_addr(struct klp_object *obj,
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory CLEMENT <[email protected]>
commit ce2f6ea1cbd41d78224f703af980a6ceeb0eb56a upstream.
The commit df59fa7f4bca "spi: orion: support armada extended baud
rates" was too optimistic for the maximum baud rate that the Armada
SoCs can support. According to the hardware datasheet the maximum
frequency supported by the Armada 370 SoC is tclk/4. But for the
Armada XP, Armada 38x and Armada 39x SoCs the limitation is 50MHz and
for the Armada 375 it is tclk/15.
Currently the armada-370-spi compatible is only used by the Armada 370
and the Armada XP device tree. On Armada 370, tclk cannot be higher
than 200MHz. In order to be able to handle both SoCs, we can take the
minimum of 50MHz and tclk/4.
A proper solution is adding a compatible string for each SoC, but it
can't be done as a fix for compatibility reason (we can't modify
device tree that have been already released) and it will be part of a
separate patch.
Fixes: df59fa7f4bca (spi: orion: support armada extended baud rates)
Reported-by: Kostya Porotchkin <[email protected]>
Signed-off-by: Gregory CLEMENT <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/spi/spi-orion.c | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -61,6 +61,12 @@ enum orion_spi_type {
struct orion_spi_dev {
enum orion_spi_type typ;
+ /*
+ * min_divisor and max_hz should be exclusive, the only we can
+ * have both is for managing the armada-370-spi case with old
+ * device tree
+ */
+ unsigned long max_hz;
unsigned int min_divisor;
unsigned int max_divisor;
u32 prescale_mask;
@@ -387,8 +393,9 @@ static const struct orion_spi_dev orion_
static const struct orion_spi_dev armada_spi_dev_data = {
.typ = ARMADA_SPI,
- .min_divisor = 1,
+ .min_divisor = 4,
.max_divisor = 1920,
+ .max_hz = 50000000,
.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
};
@@ -454,7 +461,21 @@ static int orion_spi_probe(struct platfo
goto out;
tclk_hz = clk_get_rate(spi->clk);
- master->max_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->min_divisor);
+
+ /*
+ * With old device tree, armada-370-spi could be used with
+ * Armada XP, however for this SoC the maximum frequency is
+ * 50MHz instead of tclk/4. On Armada 370, tclk cannot be
+ * higher than 200MHz. So, in order to be able to handle both
+ * SoCs, we can take the minimum of 50MHz and tclk/4.
+ */
+ if (of_device_is_compatible(pdev->dev.of_node,
+ "marvell,armada-370-spi"))
+ master->max_speed_hz = min(devdata->max_hz,
+ DIV_ROUND_UP(tclk_hz, devdata->min_divisor));
+ else
+ master->max_speed_hz =
+ DIV_ROUND_UP(tclk_hz, devdata->min_divisor);
master->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ezequiel Garcia <[email protected]>
commit ea6055c46eda1e19e02209814955e13f334bbe1b upstream.
Since commit 39a6ac11df65 ("spi/pl022: Devicetree support w/o platform data")
the 'num-cs' parameter cannot be passed through platform data when probing
with devicetree. Instead, it's a required devicetree property.
Fix the binding documentation so the property is properly specified.
Fixes: 39a6ac11df65 ("spi/pl022: Devicetree support w/o platform data")
Signed-off-by: Ezequiel Garcia <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/devicetree/bindings/spi/spi_pl022.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/spi/spi_pl022.txt
+++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt
@@ -4,9 +4,9 @@ Required properties:
- compatible : "arm,pl022", "arm,primecell"
- reg : Offset and length of the register set for the device
- interrupts : Should contain SPI controller interrupt
+- num-cs : total number of chipselects
Optional properties:
-- num-cs : total number of chipselects
- cs-gpios : should specify GPIOs used for chipselects.
The gpios will be referred to as reg = <index> in the SPI child nodes.
If unspecified, a single SPI device without a chip select can be used.
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit be34c62ddf39d1931780b07a6f4241393e4ba2ee upstream.
Introduce the helper function srp_wait_for_queuecommand().
Move the definition of scsi_request_fn_active(). Add a comment
above srp_wait_for_queuecommand() that support for scsi-mq needs
to be added.
This patch does not change any functionality. A second call to
srp_wait_for_queuecommand() will be introduced in the next patch.
Signed-off-by: Bart Van Assche <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/scsi_transport_srp.c | 54 +++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 23 deletions(-)
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -396,6 +396,36 @@ static void srp_reconnect_work(struct wo
}
}
+/**
+ * scsi_request_fn_active() - number of kernel threads inside scsi_request_fn()
+ * @shost: SCSI host for which to count the number of scsi_request_fn() callers.
+ *
+ * To do: add support for scsi-mq in this function.
+ */
+static int scsi_request_fn_active(struct Scsi_Host *shost)
+{
+ struct scsi_device *sdev;
+ struct request_queue *q;
+ int request_fn_active = 0;
+
+ shost_for_each_device(sdev, shost) {
+ q = sdev->request_queue;
+
+ spin_lock_irq(q->queue_lock);
+ request_fn_active += q->request_fn_active;
+ spin_unlock_irq(q->queue_lock);
+ }
+
+ return request_fn_active;
+}
+
+/* Wait until ongoing shost->hostt->queuecommand() calls have finished. */
+static void srp_wait_for_queuecommand(struct Scsi_Host *shost)
+{
+ while (scsi_request_fn_active(shost))
+ msleep(20);
+}
+
static void __rport_fail_io_fast(struct srp_rport *rport)
{
struct Scsi_Host *shost = rport_to_shost(rport);
@@ -504,27 +534,6 @@ void srp_start_tl_fail_timers(struct srp
EXPORT_SYMBOL(srp_start_tl_fail_timers);
/**
- * scsi_request_fn_active() - number of kernel threads inside scsi_request_fn()
- * @shost: SCSI host for which to count the number of scsi_request_fn() callers.
- */
-static int scsi_request_fn_active(struct Scsi_Host *shost)
-{
- struct scsi_device *sdev;
- struct request_queue *q;
- int request_fn_active = 0;
-
- shost_for_each_device(sdev, shost) {
- q = sdev->request_queue;
-
- spin_lock_irq(q->queue_lock);
- request_fn_active += q->request_fn_active;
- spin_unlock_irq(q->queue_lock);
- }
-
- return request_fn_active;
-}
-
-/**
* srp_reconnect_rport() - reconnect to an SRP target port
* @rport: SRP target port.
*
@@ -559,8 +568,7 @@ int srp_reconnect_rport(struct srp_rport
if (res)
goto out;
scsi_target_block(&shost->shost_gendev);
- while (scsi_request_fn_active(shost))
- msleep(20);
+ srp_wait_for_queuecommand(shost);
res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV;
pr_debug("%s (state %d): transport.reconnect() returned %d\n",
dev_name(&shost->shost_gendev), rport->state, res);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 535fb906225fb7436cb658144d0c0cea14a26f3e upstream.
Avoid that srp_terminate_io() can get invoked while srp_queuecommand()
is in progress. This patch avoids that an I/O timeout can trigger the
following kernel warning:
WARNING: at drivers/infiniband/ulp/srp/ib_srp.c:1447 srp_terminate_io+0xef/0x100 [ib_srp]()
Call Trace:
[<ffffffff814c65a2>] dump_stack+0x4e/0x68
[<ffffffff81051f71>] warn_slowpath_common+0x81/0xa0
[<ffffffff8105204a>] warn_slowpath_null+0x1a/0x20
[<ffffffffa075f51f>] srp_terminate_io+0xef/0x100 [ib_srp]
[<ffffffffa07495da>] __rport_fail_io_fast+0xba/0xc0 [scsi_transport_srp]
[<ffffffffa0749a90>] rport_fast_io_fail_timedout+0xe0/0xf0 [scsi_transport_srp]
[<ffffffff8106e09b>] process_one_work+0x1db/0x780
[<ffffffff8106e75b>] worker_thread+0x11b/0x450
[<ffffffff81073c64>] kthread+0xe4/0x100
[<ffffffff814cf26c>] ret_from_fork+0x7c/0xb0
See also patch "scsi_transport_srp: Add transport layer error
handling" (commit ID 29c17324803c).
Signed-off-by: Bart Van Assche <[email protected]>
Cc: James Bottomley <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/scsi/scsi_transport_srp.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -439,8 +439,10 @@ static void __rport_fail_io_fast(struct
/* Involve the LLD if possible to terminate all I/O on the rport. */
i = to_srp_internal(shost->transportt);
- if (i->f->terminate_rport_io)
+ if (i->f->terminate_rport_io) {
+ srp_wait_for_queuecommand(shost);
i->f->terminate_rport_io(rport);
+ }
}
/**
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit fb49c8bbaae70b14fea2b4590a90a21539f88526 upstream.
Fix a scsi_get_host() / scsi_host_put() imbalance in the error
path of srp_create_target(). See also patch "IB/srp: Avoid that
I/O hangs due to a cable pull during LUN scanning" (commit ID
34aa654ecb8e).
Signed-off-by: Bart Van Assche <[email protected]>
Reviewed-by: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3171,11 +3171,11 @@ static ssize_t srp_create_target(struct
ret = srp_parse_options(buf, target);
if (ret)
- goto err;
+ goto out;
ret = scsi_init_shared_tag_map(target_host, target_host->can_queue);
if (ret)
- goto err;
+ goto out;
target->req_ring_size = target->queue_size - SRP_TSK_MGMT_SQ_SIZE;
@@ -3186,7 +3186,7 @@ static ssize_t srp_create_target(struct
be64_to_cpu(target->ioc_guid),
be64_to_cpu(target->initiator_ext));
ret = -EEXIST;
- goto err;
+ goto out;
}
if (!srp_dev->has_fmr && !srp_dev->has_fr && !target->allow_ext_sg &&
@@ -3207,7 +3207,7 @@ static ssize_t srp_create_target(struct
spin_lock_init(&target->lock);
ret = ib_query_gid(ibdev, host->port, 0, &target->sgid);
if (ret)
- goto err;
+ goto out;
ret = -ENOMEM;
target->ch_count = max_t(unsigned, num_online_nodes(),
@@ -3218,7 +3218,7 @@ static ssize_t srp_create_target(struct
target->ch = kcalloc(target->ch_count, sizeof(*target->ch),
GFP_KERNEL);
if (!target->ch)
- goto err;
+ goto out;
node_idx = 0;
for_each_online_node(node) {
@@ -3314,9 +3314,6 @@ err_disconnect:
}
kfree(target->ch);
-
-err:
- scsi_host_put(target_host);
goto out;
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 8de9fe3a1d4ac8c3e4953fa4b7d81f863f5196ad upstream.
Avoid that receiving a DREQ while RDMA channels are being
established causes target->qp_in_error to be reset.
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -992,8 +992,6 @@ static int srp_connect_ch(struct srp_rdm
WARN_ON_ONCE(!multich && target->connected);
- target->qp_in_error = false;
-
ret = srp_lookup_path(ch);
if (ret)
return ret;
@@ -1242,6 +1240,9 @@ static int srp_rport_reconnect(struct sr
for (j = 0; j < target->queue_size; ++j)
list_add(&ch->tx_ring[j]->list, &ch->free_tx);
}
+
+ target->qp_in_error = false;
+
for (i = 0; i < target->ch_count; i++) {
ch = &target->ch[i];
if (ret || !ch->target) {
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit c014c8cd31b161e12deb81c0f7f477811bd1eddc upstream.
Reception of a DREQ message only causes the state of a single
channel to change. Hence move the 'connected' member variable
from the target to the channel data structure. This patch
avoids that following false positive warning can be reported
by srp_destroy_qp():
WARNING: at drivers/infiniband/ulp/srp/ib_srp.c:617 srp_destroy_qp+0xa6/0x120 [ib_srp]()
Call Trace:
[<ffffffff8106e10f>] warn_slowpath_common+0x7f/0xc0
[<ffffffff8106e16a>] warn_slowpath_null+0x1a/0x20
[<ffffffffa0440226>] srp_destroy_qp+0xa6/0x120 [ib_srp]
[<ffffffffa0440322>] srp_free_ch_ib+0x82/0x1e0 [ib_srp]
[<ffffffffa044408b>] srp_create_target+0x7ab/0x998 [ib_srp]
[<ffffffff81346f60>] dev_attr_store+0x20/0x30
[<ffffffff811dd90f>] sysfs_write_file+0xef/0x170
[<ffffffff8116d248>] vfs_write+0xc8/0x190
[<ffffffff8116d411>] sys_write+0x51/0x90
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 60 +++++++++++++++++-------------------
drivers/infiniband/ulp/srp/ib_srp.h | 2 -
2 files changed, 30 insertions(+), 32 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -464,14 +464,13 @@ static struct srp_fr_pool *srp_alloc_fr_
*/
static void srp_destroy_qp(struct srp_rdma_ch *ch)
{
- struct srp_target_port *target = ch->target;
static struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };
static struct ib_recv_wr wr = { .wr_id = SRP_LAST_WR_ID };
struct ib_recv_wr *bad_wr;
int ret;
/* Destroying a QP and reusing ch->done is only safe if not connected */
- WARN_ON_ONCE(target->connected);
+ WARN_ON_ONCE(ch->connected);
ret = ib_modify_qp(ch->qp, &attr, IB_QP_STATE);
WARN_ONCE(ret, "ib_cm_init_qp_attr() returned %d\n", ret);
@@ -810,35 +809,19 @@ static bool srp_queue_remove_work(struct
return changed;
}
-static bool srp_change_conn_state(struct srp_target_port *target,
- bool connected)
-{
- bool changed = false;
-
- spin_lock_irq(&target->lock);
- if (target->connected != connected) {
- target->connected = connected;
- changed = true;
- }
- spin_unlock_irq(&target->lock);
-
- return changed;
-}
-
static void srp_disconnect_target(struct srp_target_port *target)
{
struct srp_rdma_ch *ch;
int i;
- if (srp_change_conn_state(target, false)) {
- /* XXX should send SRP_I_LOGOUT request */
+ /* XXX should send SRP_I_LOGOUT request */
- for (i = 0; i < target->ch_count; i++) {
- ch = &target->ch[i];
- if (ch->cm_id && ib_send_cm_dreq(ch->cm_id, NULL, 0)) {
- shost_printk(KERN_DEBUG, target->scsi_host,
- PFX "Sending CM DREQ failed\n");
- }
+ for (i = 0; i < target->ch_count; i++) {
+ ch = &target->ch[i];
+ ch->connected = false;
+ if (ch->cm_id && ib_send_cm_dreq(ch->cm_id, NULL, 0)) {
+ shost_printk(KERN_DEBUG, target->scsi_host,
+ PFX "Sending CM DREQ failed\n");
}
}
}
@@ -985,12 +968,26 @@ static void srp_rport_delete(struct srp_
srp_queue_remove_work(target);
}
+/**
+ * srp_connected_ch() - number of connected channels
+ * @target: SRP target port.
+ */
+static int srp_connected_ch(struct srp_target_port *target)
+{
+ int i, c = 0;
+
+ for (i = 0; i < target->ch_count; i++)
+ c += target->ch[i].connected;
+
+ return c;
+}
+
static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich)
{
struct srp_target_port *target = ch->target;
int ret;
- WARN_ON_ONCE(!multich && target->connected);
+ WARN_ON_ONCE(!multich && srp_connected_ch(target) > 0);
ret = srp_lookup_path(ch);
if (ret)
@@ -1013,7 +1010,7 @@ static int srp_connect_ch(struct srp_rdm
*/
switch (ch->status) {
case 0:
- srp_change_conn_state(target, true);
+ ch->connected = true;
return 0;
case SRP_PORT_REDIRECT:
@@ -1929,7 +1926,7 @@ static void srp_handle_qp_err(u64 wr_id,
return;
}
- if (target->connected && !target->qp_in_error) {
+ if (ch->connected && !target->qp_in_error) {
if (wr_id & LOCAL_INV_WR_ID_MASK) {
shost_printk(KERN_ERR, target->scsi_host, PFX
"LOCAL_INV failed with status %d\n",
@@ -2367,7 +2364,7 @@ static int srp_cm_handler(struct ib_cm_i
case IB_CM_DREQ_RECEIVED:
shost_printk(KERN_WARNING, target->scsi_host,
PFX "DREQ received - connection closed\n");
- srp_change_conn_state(target, false);
+ ch->connected = false;
if (ib_send_cm_drep(cm_id, NULL, 0))
shost_printk(KERN_ERR, target->scsi_host,
PFX "Sending CM DREP failed\n");
@@ -2423,7 +2420,7 @@ static int srp_send_tsk_mgmt(struct srp_
struct srp_iu *iu;
struct srp_tsk_mgmt *tsk_mgmt;
- if (!target->connected || target->qp_in_error)
+ if (!ch->connected || target->qp_in_error)
return -1;
init_completion(&ch->tsk_mgmt_done);
@@ -2797,7 +2794,8 @@ static int srp_add_target(struct srp_hos
scsi_scan_target(&target->scsi_host->shost_gendev,
0, target->scsi_id, SCAN_WILD_CARD, 0);
- if (!target->connected || target->qp_in_error) {
+ if (srp_connected_ch(target) < target->ch_count ||
+ target->qp_in_error) {
shost_printk(KERN_INFO, target->scsi_host,
PFX "SCSI scan failed - removing SCSI host\n");
srp_queue_remove_work(target);
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -170,6 +170,7 @@ struct srp_rdma_ch {
struct completion tsk_mgmt_done;
u8 tsk_mgmt_status;
+ bool connected;
};
/**
@@ -214,7 +215,6 @@ struct srp_target_port {
__be16 pkey;
u32 rq_tmo_jiffies;
- bool connected;
int zero_req_lim;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit a44074f14ba1ea0747ea737026eb929b81993dc3 upstream.
Although it is possible to let SRP I/O continue if a reconnect
results in a reduction of the number of channels, the current
code does not handle this scenario correctly. Instead of making
the reconnect code more complex, consider this as a reconnection
failure.
Signed-off-by: Bart Van Assche <[email protected]>
Cc: Sagi Grimberg <[email protected]>
Cc: Sebastian Parschauer <[email protected]>
Signed-off-by: Doug Ledford <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/infiniband/ulp/srp/ib_srp.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1242,11 +1242,8 @@ static int srp_rport_reconnect(struct sr
for (i = 0; i < target->ch_count; i++) {
ch = &target->ch[i];
- if (ret || !ch->target) {
- if (i > 1)
- ret = 0;
+ if (ret || !ch->target)
break;
- }
ret = srp_connect_ch(ch, multich);
multich = true;
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Lin <[email protected]>
commit 63781394c540dd9e666a6b21d70b64dd52bce76e upstream.
request_any_context_irq() returns a negative value on failure.
It returns either IRQC_IS_HARDIRQ or IRQC_IS_NESTED on success.
So fix testing return value of request_any_context_irq().
Also fixup the return value of devm_request_any_context_irq() to make it
consistent with request_any_context_irq().
Fixes: 0668d3065128 ("genirq: Add devm_request_any_context_irq()")
Signed-off-by: Axel Lin <[email protected]>
Reviewed-by: Stephen Boyd <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
kernel/irq/devres.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/irq/devres.c
+++ b/kernel/irq/devres.c
@@ -104,7 +104,7 @@ int devm_request_any_context_irq(struct
return -ENOMEM;
rc = request_any_context_irq(irq, handler, irqflags, devname, dev_id);
- if (rc) {
+ if (rc < 0) {
devres_free(dr);
return rc;
}
@@ -113,7 +113,7 @@ int devm_request_any_context_irq(struct
dr->dev_id = dev_id;
devres_add(dev, dr);
- return 0;
+ return rc;
}
EXPORT_SYMBOL(devm_request_any_context_irq);
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Ying <[email protected]>
commit 2fa3b4c4a78a5db3502ab9e32630ea660ff923d0 upstream.
The LCDIF engines embedded in i.MX6sl and i.MX6sx SoCs need the axi clock
as the engine's system clock. The clock should be enabled when accessing
LCDIF registers, otherwise the kernel would hang up. We should also keep
the clock enabled when the engine is being active to scan out frames from
memory. This patch makes sure the axi clock is enabled when accessing
registers so that the kernel hang up issue can be fixed.
Reported-by: Peter Chen <[email protected]>
Tested-by: Peter Chen <[email protected]>
Signed-off-by: Liu Ying <[email protected]>
Signed-off-by: Tomi Valkeinen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/video/fbdev/mxsfb.c | 68 ++++++++++++++++++++++++++++++++++----------
1 file changed, 54 insertions(+), 14 deletions(-)
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -316,6 +316,18 @@ static int mxsfb_check_var(struct fb_var
return 0;
}
+static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host)
+{
+ if (host->clk_axi)
+ clk_prepare_enable(host->clk_axi);
+}
+
+static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
+{
+ if (host->clk_axi)
+ clk_disable_unprepare(host->clk_axi);
+}
+
static void mxsfb_enable_controller(struct fb_info *fb_info)
{
struct mxsfb_info *host = to_imxfb_host(fb_info);
@@ -333,14 +345,13 @@ static void mxsfb_enable_controller(stru
}
}
- if (host->clk_axi)
- clk_prepare_enable(host->clk_axi);
-
if (host->clk_disp_axi)
clk_prepare_enable(host->clk_disp_axi);
clk_prepare_enable(host->clk);
clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
+ mxsfb_enable_axi_clk(host);
+
/* if it was disabled, re-enable the mode again */
writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
@@ -380,11 +391,11 @@ static void mxsfb_disable_controller(str
reg = readl(host->base + LCDC_VDCTRL4);
writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
+ mxsfb_disable_axi_clk(host);
+
clk_disable_unprepare(host->clk);
if (host->clk_disp_axi)
clk_disable_unprepare(host->clk_disp_axi);
- if (host->clk_axi)
- clk_disable_unprepare(host->clk_axi);
host->enabled = 0;
@@ -421,6 +432,8 @@ static int mxsfb_set_par(struct fb_info
mxsfb_disable_controller(fb_info);
}
+ mxsfb_enable_axi_clk(host);
+
/* clear the FIFOs */
writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
@@ -438,6 +451,7 @@ static int mxsfb_set_par(struct fb_info
ctrl |= CTRL_SET_WORD_LENGTH(3);
switch (host->ld_intf_width) {
case STMLCDIF_8BIT:
+ mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev,
"Unsupported LCD bus width mapping\n");
return -EINVAL;
@@ -451,6 +465,7 @@ static int mxsfb_set_par(struct fb_info
writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
break;
default:
+ mxsfb_disable_axi_clk(host);
dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
fb_info->var.bits_per_pixel);
return -EINVAL;
@@ -504,6 +519,8 @@ static int mxsfb_set_par(struct fb_info
fb_info->fix.line_length * fb_info->var.yoffset,
host->base + host->devdata->next_buf);
+ mxsfb_disable_axi_clk(host);
+
if (reenable)
mxsfb_enable_controller(fb_info);
@@ -582,10 +599,14 @@ static int mxsfb_pan_display(struct fb_v
offset = fb_info->fix.line_length * var->yoffset;
+ mxsfb_enable_axi_clk(host);
+
/* update on next VSYNC */
writel(fb_info->fix.smem_start + offset,
host->base + host->devdata->next_buf);
+ mxsfb_disable_axi_clk(host);
+
return 0;
}
@@ -608,13 +629,17 @@ static int mxsfb_restore_mode(struct mxs
unsigned line_count;
unsigned period;
unsigned long pa, fbsize;
- int bits_per_pixel, ofs;
+ int bits_per_pixel, ofs, ret = 0;
u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
+ mxsfb_enable_axi_clk(host);
+
/* Only restore the mode when the controller is running */
ctrl = readl(host->base + LCDC_CTRL);
- if (!(ctrl & CTRL_RUN))
- return -EINVAL;
+ if (!(ctrl & CTRL_RUN)) {
+ ret = -EINVAL;
+ goto err;
+ }
vdctrl0 = readl(host->base + LCDC_VDCTRL0);
vdctrl2 = readl(host->base + LCDC_VDCTRL2);
@@ -635,7 +660,8 @@ static int mxsfb_restore_mode(struct mxs
break;
case 1:
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
}
fb_info->var.bits_per_pixel = bits_per_pixel;
@@ -673,10 +699,14 @@ static int mxsfb_restore_mode(struct mxs
pa = readl(host->base + host->devdata->cur_buf);
fbsize = fb_info->fix.line_length * vmode->yres;
- if (pa < fb_info->fix.smem_start)
- return -EINVAL;
- if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len)
- return -EINVAL;
+ if (pa < fb_info->fix.smem_start) {
+ ret = -EINVAL;
+ goto err;
+ }
+ if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) {
+ ret = -EINVAL;
+ goto err;
+ }
ofs = pa - fb_info->fix.smem_start;
if (ofs) {
memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
@@ -689,7 +719,11 @@ static int mxsfb_restore_mode(struct mxs
clk_prepare_enable(host->clk);
host->enabled = 1;
- return 0;
+err:
+ if (ret)
+ mxsfb_disable_axi_clk(host);
+
+ return ret;
}
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
@@ -915,7 +949,9 @@ static int mxsfb_probe(struct platform_d
}
if (!host->enabled) {
+ mxsfb_enable_axi_clk(host);
writel(0, host->base + LCDC_CTRL);
+ mxsfb_disable_axi_clk(host);
mxsfb_set_par(fb_info);
mxsfb_enable_controller(fb_info);
}
@@ -954,11 +990,15 @@ static void mxsfb_shutdown(struct platfo
struct fb_info *fb_info = platform_get_drvdata(pdev);
struct mxsfb_info *host = to_imxfb_host(fb_info);
+ mxsfb_enable_axi_clk(host);
+
/*
* Force stop the LCD controller as keeping it running during reboot
* might interfere with the BootROM's boot mode pads sampling.
*/
writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
+
+ mxsfb_disable_axi_clk(host);
}
static struct platform_driver mxsfb_driver = {
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Grygorii Strashko <[email protected]>
commit 084609bf727981c7a2e6e69aefe0052c9d793300 upstream.
Setting a dev_pm_ops suspend/resume pair of callbacks but not a set of
hibernation callbacks means those pm functions will not be
called upon hibernation - that leads to system crash on ARM during
freezing if gpio-led is used in combination with CPU led trigger.
It may happen after freeze_noirq stage (GPIO is suspended)
and before syscore_suspend stage (CPU led trigger is suspended)
- usually when disable_nonboot_cpus() is called.
Log:
PM: noirq freeze of devices complete after 1.425 msecs
Disabling non-boot CPUs ...
^ system may crash or stuck here with message (TI AM572x)
WARNING: CPU: 0 PID: 3100 at drivers/bus/omap_l3_noc.c:148 l3_interrupt_handler+0x22c/0x370()
44000000.ocp:L3 Custom Error: MASTER MPU TARGET L4_PER1_P3 (Idle): Data Access in Supervisor mode during Functional access
CPU1: shutdown
^ or here
Fix this by using SIMPLE_DEV_PM_OPS, which appropriately
assigns the suspend and hibernation callbacks and move
led_suspend/led_resume under CONFIG_PM_SLEEP to avoid
build warnings.
Fixes: 73e1ab41a80d (leds: Convert led class driver from legacy pm ops to dev_pm_ops)
Signed-off-by: Grygorii Strashko <[email protected]>
Acked-by: Jacek Anaszewski <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/leds/led-class.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -187,6 +187,7 @@ void led_classdev_resume(struct led_clas
}
EXPORT_SYMBOL_GPL(led_classdev_resume);
+#ifdef CONFIG_PM_SLEEP
static int led_suspend(struct device *dev)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -206,11 +207,9 @@ static int led_resume(struct device *dev
return 0;
}
+#endif
-static const struct dev_pm_ops leds_class_dev_pm_ops = {
- .suspend = led_suspend,
- .resume = led_resume,
-};
+static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
/**
* led_classdev_register - register a new object of led_classdev class.
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Norris <[email protected]>
commit 073db4a51ee43ccb827f54a4261c0583b028d5ab upstream.
On A MIPS 32-cores machine a BUG_ON was triggered because some acesses to
mtd->usecount were done without taking mtd_table_mutex.
kernel: Call Trace:
kernel: [<ffffffff80401818>] __put_mtd_device+0x20/0x50
kernel: [<ffffffff804086f4>] blktrans_release+0x8c/0xd8
kernel: [<ffffffff802577e0>] __blkdev_put+0x1a8/0x200
kernel: [<ffffffff802579a4>] blkdev_close+0x1c/0x30
kernel: [<ffffffff8022006c>] __fput+0xac/0x250
kernel: [<ffffffff80171208>] task_work_run+0xd8/0x120
kernel: [<ffffffff8012c23c>] work_notifysig+0x10/0x18
kernel:
kernel:
Code: 2442ffff ac8202d8 000217fe <00020336> dc820128 10400003
00000000 0040f809 00000000
kernel: ---[ end trace 080fbb4579b47a73 ]---
Fixed by taking the mutex in blktrans_open and blktrans_release.
Note that this locking is already suggested in
include/linux/mtd/blktrans.h:
struct mtd_blktrans_ops {
...
/* Called with mtd_table_mutex held; no race with add/remove */
int (*open)(struct mtd_blktrans_dev *dev);
void (*release)(struct mtd_blktrans_dev *dev);
...
};
But we weren't following it.
Originally reported by (and patched by) Zhang and Giuseppe,
independently. Improved and rewritten.
Reported-by: Zhang Xingcai <[email protected]>
Reported-by: Giuseppe Cantavenera <[email protected]>
Tested-by: Giuseppe Cantavenera <[email protected]>
Acked-by: Alexander Sverdlin <[email protected]>
Signed-off-by: Brian Norris <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/mtd/mtd_blkdevs.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -200,6 +200,7 @@ static int blktrans_open(struct block_de
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
mutex_lock(&dev->lock);
+ mutex_lock(&mtd_table_mutex);
if (dev->open)
goto unlock;
@@ -223,6 +224,7 @@ static int blktrans_open(struct block_de
unlock:
dev->open++;
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
return ret;
@@ -233,6 +235,7 @@ error_release:
error_put:
module_put(dev->tr->owner);
kref_put(&dev->ref, blktrans_dev_release);
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
return ret;
@@ -246,6 +249,7 @@ static void blktrans_release(struct gend
return;
mutex_lock(&dev->lock);
+ mutex_lock(&mtd_table_mutex);
if (--dev->open)
goto unlock;
@@ -259,6 +263,7 @@ static void blktrans_release(struct gend
__put_mtd_device(dev->mtd);
}
unlock:
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
}
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Rafael J. Wysocki" <[email protected]>
commit 0824965140fff1bf640a987dc790d1594a8e0699 upstream.
Refine the mechanism introduced by commit f244d8b623da ("ACPIPHP / radeon /
nouveau: Fix VGA switcheroo problem related to hotplug") to propagate the
ignore_hotplug setting of the device to its parent bridge in case hotplug
notifications related to the graphics adapter switching are given for the
bridge rather than for the device itself (they need to be ignored in both
cases).
Link: https://bugzilla.kernel.org/show_bug.cgi?id=61891
Link: https://bugs.freedesktop.org/show_bug.cgi?id=88927
Fixes: b440bde74f04 ("PCI: Add pci_ignore_hotplug() to ignore hotplug events for a device")
Reported-and-tested-by: tiagdtd-lava <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pci/pci.c | 11 +++++++++++
include/linux/pci.h | 6 +-----
2 files changed, 12 insertions(+), 5 deletions(-)
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4319,6 +4319,17 @@ bool pci_device_is_present(struct pci_de
}
EXPORT_SYMBOL_GPL(pci_device_is_present);
+void pci_ignore_hotplug(struct pci_dev *dev)
+{
+ struct pci_dev *bridge = dev->bus->self;
+
+ dev->ignore_hotplug = 1;
+ /* Propagate the "ignore hotplug" setting to the parent bridge. */
+ if (bridge)
+ bridge->ignore_hotplug = 1;
+}
+EXPORT_SYMBOL_GPL(pci_ignore_hotplug);
+
#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
static DEFINE_SPINLOCK(resource_alignment_lock);
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1002,6 +1002,7 @@ int __must_check pci_assign_resource(str
int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
bool pci_device_is_present(struct pci_dev *pdev);
+void pci_ignore_hotplug(struct pci_dev *dev);
/* ROM control related routines */
int pci_enable_rom(struct pci_dev *pdev);
@@ -1039,11 +1040,6 @@ bool pci_dev_run_wake(struct pci_dev *de
bool pci_check_pme_status(struct pci_dev *dev);
void pci_pme_wakeup_bus(struct pci_bus *bus);
-static inline void pci_ignore_hotplug(struct pci_dev *dev)
-{
- dev->ignore_hotplug = 1;
-}
-
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
bool enable)
{
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yinghai Lu <[email protected]>
commit 3a9ad0b4fdcd57f775d3615004c8c64c021a9e7d upstream.
David Ahern reported that d63e2e1f3df9 ("sparc/PCI: Clip bridge windows
to fit in upstream windows") fails to boot on sparc/T5-8:
pci 0000:06:00.0: reg 0x184: can't handle BAR above 4GB (bus address 0x110204000)
The problem is that sparc64 assumed that dma_addr_t only needed to hold DMA
addresses, i.e., bus addresses returned via the DMA API (dma_map_single(),
etc.), while the PCI core assumed dma_addr_t could hold *any* bus address,
including raw BAR values. On sparc64, all DMA addresses fit in 32 bits, so
dma_addr_t is a 32-bit type. However, BAR values can be 64 bits wide, so
they don't fit in a dma_addr_t. d63e2e1f3df9 added new checking that
tripped over this mismatch.
Add pci_bus_addr_t, which is wide enough to hold any PCI bus address,
including both raw BAR values and DMA addresses. This will be 64 bits
on 64-bit platforms and on platforms with a 64-bit dma_addr_t. Then
dma_addr_t only needs to be wide enough to hold addresses from the DMA API.
[bhelgaas: changelog, bugzilla, Kconfig to ensure pci_bus_addr_t is at
least as wide as dma_addr_t, documentation]
Fixes: d63e2e1f3df9 ("sparc/PCI: Clip bridge windows to fit in upstream windows")
Fixes: 23b13bc76f35 ("PCI: Fail safely if we can't handle BARs larger than 4GB")
Link: http://lkml.kernel.org/r/CAE9FiQU1gJY1LYrxs+ma5LCTEEe4xmtjRG0aXJ9K_Tsu+m9Wuw@mail.gmail.com
Link: http://lkml.kernel.org/r/[email protected]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=96231
Reported-by: David Ahern <[email protected]>
Tested-by: David Ahern <[email protected]>
Signed-off-by: Yinghai Lu <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Acked-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
Documentation/DMA-API-HOWTO.txt | 29 +++++++++++++++++------------
Documentation/DMA-API.txt | 30 +++++++++++++++---------------
drivers/pci/Kconfig | 4 ++++
drivers/pci/bus.c | 10 +++++-----
drivers/pci/probe.c | 12 ++++++------
include/linux/pci.h | 12 +++++++++---
include/linux/types.h | 12 ++++++++++--
7 files changed, 66 insertions(+), 43 deletions(-)
--- a/Documentation/DMA-API-HOWTO.txt
+++ b/Documentation/DMA-API-HOWTO.txt
@@ -25,13 +25,18 @@ physical addresses. These are the addre
address is not directly useful to a driver; it must use ioremap() to map
the space and produce a virtual address.
-I/O devices use a third kind of address: a "bus address" or "DMA address".
-If a device has registers at an MMIO address, or if it performs DMA to read
-or write system memory, the addresses used by the device are bus addresses.
-In some systems, bus addresses are identical to CPU physical addresses, but
-in general they are not. IOMMUs and host bridges can produce arbitrary
+I/O devices use a third kind of address: a "bus address". If a device has
+registers at an MMIO address, or if it performs DMA to read or write system
+memory, the addresses used by the device are bus addresses. In some
+systems, bus addresses are identical to CPU physical addresses, but in
+general they are not. IOMMUs and host bridges can produce arbitrary
mappings between physical and bus addresses.
+From a device's point of view, DMA uses the bus address space, but it may
+be restricted to a subset of that space. For example, even if a system
+supports 64-bit addresses for main memory and PCI BARs, it may use an IOMMU
+so devices only need to use 32-bit DMA addresses.
+
Here's a picture and some examples:
CPU CPU Bus
@@ -72,11 +77,11 @@ can use virtual address X to access the
cannot because DMA doesn't go through the CPU virtual memory system.
In some simple systems, the device can do DMA directly to physical address
-Y. But in many others, there is IOMMU hardware that translates bus
+Y. But in many others, there is IOMMU hardware that translates DMA
addresses to physical addresses, e.g., it translates Z to Y. This is part
of the reason for the DMA API: the driver can give a virtual address X to
an interface like dma_map_single(), which sets up any required IOMMU
-mapping and returns the bus address Z. The driver then tells the device to
+mapping and returns the DMA address Z. The driver then tells the device to
do DMA to Z, and the IOMMU maps it to the buffer at address Y in system
RAM.
@@ -98,7 +103,7 @@ First of all, you should make sure
#include <linux/dma-mapping.h>
is in your driver, which provides the definition of dma_addr_t. This type
-can hold any valid DMA or bus address for the platform and should be used
+can hold any valid DMA address for the platform and should be used
everywhere you hold a DMA address returned from the DMA mapping functions.
What memory is DMA'able?
@@ -316,7 +321,7 @@ There are two types of DMA mappings:
Think of "consistent" as "synchronous" or "coherent".
The current default is to return consistent memory in the low 32
- bits of the bus space. However, for future compatibility you should
+ bits of the DMA space. However, for future compatibility you should
set the consistent mask even if this default is fine for your
driver.
@@ -403,7 +408,7 @@ dma_alloc_coherent() returns two values:
can use to access it from the CPU and dma_handle which you pass to the
card.
-The CPU virtual address and the DMA bus address are both
+The CPU virtual address and the DMA address are both
guaranteed to be aligned to the smallest PAGE_SIZE order which
is greater than or equal to the requested size. This invariant
exists (for example) to guarantee that if you allocate a chunk
@@ -645,8 +650,8 @@ PLEASE NOTE: The 'nents' argument to th
dma_map_sg call.
Every dma_map_{single,sg}() call should have its dma_unmap_{single,sg}()
-counterpart, because the bus address space is a shared resource and
-you could render the machine unusable by consuming all bus addresses.
+counterpart, because the DMA address space is a shared resource and
+you could render the machine unusable by consuming all DMA addresses.
If you need to use the same streaming DMA region multiple times and touch
the data in between the DMA transfers, the buffer needs to be synced
--- a/Documentation/DMA-API.txt
+++ b/Documentation/DMA-API.txt
@@ -18,10 +18,10 @@ Part I - dma_ API
To get the dma_ API, you must #include <linux/dma-mapping.h>. This
provides dma_addr_t and the interfaces described below.
-A dma_addr_t can hold any valid DMA or bus address for the platform. It
-can be given to a device to use as a DMA source or target. A CPU cannot
-reference a dma_addr_t directly because there may be translation between
-its physical address space and the bus address space.
+A dma_addr_t can hold any valid DMA address for the platform. It can be
+given to a device to use as a DMA source or target. A CPU cannot reference
+a dma_addr_t directly because there may be translation between its physical
+address space and the DMA address space.
Part Ia - Using large DMA-coherent buffers
------------------------------------------
@@ -42,7 +42,7 @@ It returns a pointer to the allocated re
address space) or NULL if the allocation failed.
It also returns a <dma_handle> which may be cast to an unsigned integer the
-same width as the bus and given to the device as the bus address base of
+same width as the bus and given to the device as the DMA address base of
the region.
Note: consistent memory can be expensive on some platforms, and the
@@ -193,7 +193,7 @@ dma_map_single(struct device *dev, void
enum dma_data_direction direction)
Maps a piece of processor virtual memory so it can be accessed by the
-device and returns the bus address of the memory.
+device and returns the DMA address of the memory.
The direction for both APIs may be converted freely by casting.
However the dma_ API uses a strongly typed enumerator for its
@@ -212,20 +212,20 @@ contiguous piece of memory. For this re
this API should be obtained from sources which guarantee it to be
physically contiguous (like kmalloc).
-Further, the bus address of the memory must be within the
+Further, the DMA address of the memory must be within the
dma_mask of the device (the dma_mask is a bit mask of the
-addressable region for the device, i.e., if the bus address of
-the memory ANDed with the dma_mask is still equal to the bus
+addressable region for the device, i.e., if the DMA address of
+the memory ANDed with the dma_mask is still equal to the DMA
address, then the device can perform DMA to the memory). To
ensure that the memory allocated by kmalloc is within the dma_mask,
the driver may specify various platform-dependent flags to restrict
-the bus address range of the allocation (e.g., on x86, GFP_DMA
-guarantees to be within the first 16MB of available bus addresses,
+the DMA address range of the allocation (e.g., on x86, GFP_DMA
+guarantees to be within the first 16MB of available DMA addresses,
as required by ISA devices).
Note also that the above constraints on physical contiguity and
dma_mask may not apply if the platform has an IOMMU (a device which
-maps an I/O bus address to a physical memory address). However, to be
+maps an I/O DMA address to a physical memory address). However, to be
portable, device driver writers may *not* assume that such an IOMMU
exists.
@@ -296,7 +296,7 @@ reduce current DMA mapping usage or dela
dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction)
-Returns: the number of bus address segments mapped (this may be shorter
+Returns: the number of DMA address segments mapped (this may be shorter
than <nents> passed in if some elements of the scatter/gather list are
physically or virtually adjacent and an IOMMU maps them with a single
entry).
@@ -340,7 +340,7 @@ must be the same as those and passed in
API.
Note: <nents> must be the number you passed in, *not* the number of
-bus address entries returned.
+DMA address entries returned.
void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
@@ -507,7 +507,7 @@ it's asked for coherent memory for this
phys_addr is the CPU physical address to which the memory is currently
assigned (this will be ioremapped so the CPU can access the region).
-device_addr is the bus address the device needs to be programmed
+device_addr is the DMA address the device needs to be programmed
with to actually address this memory (this will be handed out as the
dma_addr_t in dma_alloc_coherent()).
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -1,6 +1,10 @@
#
# PCI configuration
#
+config PCI_BUS_ADDR_T_64BIT
+ def_bool y if (ARCH_DMA_ADDR_T_64BIT || 64BIT)
+ depends on PCI
+
config PCI_MSI
bool "Message Signaled Interrupts (MSI and MSI-X)"
depends on PCI
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -92,11 +92,11 @@ void pci_bus_remove_resources(struct pci
}
static struct pci_bus_region pci_32_bit = {0, 0xffffffffULL};
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
static struct pci_bus_region pci_64_bit = {0,
- (dma_addr_t) 0xffffffffffffffffULL};
-static struct pci_bus_region pci_high = {(dma_addr_t) 0x100000000ULL,
- (dma_addr_t) 0xffffffffffffffffULL};
+ (pci_bus_addr_t) 0xffffffffffffffffULL};
+static struct pci_bus_region pci_high = {(pci_bus_addr_t) 0x100000000ULL,
+ (pci_bus_addr_t) 0xffffffffffffffffULL};
#endif
/*
@@ -200,7 +200,7 @@ int pci_bus_alloc_resource(struct pci_bu
resource_size_t),
void *alignf_data)
{
-#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
int rc;
if (res->flags & IORESOURCE_MEM_64) {
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -253,8 +253,8 @@ int __pci_read_base(struct pci_dev *dev,
}
if (res->flags & IORESOURCE_MEM_64) {
- if ((sizeof(dma_addr_t) < 8 || sizeof(resource_size_t) < 8) &&
- sz64 > 0x100000000ULL) {
+ if ((sizeof(pci_bus_addr_t) < 8 || sizeof(resource_size_t) < 8)
+ && sz64 > 0x100000000ULL) {
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
res->start = 0;
res->end = 0;
@@ -263,7 +263,7 @@ int __pci_read_base(struct pci_dev *dev,
goto out;
}
- if ((sizeof(dma_addr_t) < 8) && l) {
+ if ((sizeof(pci_bus_addr_t) < 8) && l) {
/* Above 32-bit boundary; try to reallocate */
res->flags |= IORESOURCE_UNSET;
res->start = 0;
@@ -398,7 +398,7 @@ static void pci_read_bridge_mmio_pref(st
struct pci_dev *dev = child->self;
u16 mem_base_lo, mem_limit_lo;
u64 base64, limit64;
- dma_addr_t base, limit;
+ pci_bus_addr_t base, limit;
struct pci_bus_region region;
struct resource *res;
@@ -425,8 +425,8 @@ static void pci_read_bridge_mmio_pref(st
}
}
- base = (dma_addr_t) base64;
- limit = (dma_addr_t) limit64;
+ base = (pci_bus_addr_t) base64;
+ limit = (pci_bus_addr_t) limit64;
if (base != base64) {
dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -573,9 +573,15 @@ int raw_pci_read(unsigned int domain, un
int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 val);
+#ifdef CONFIG_PCI_BUS_ADDR_T_64BIT
+typedef u64 pci_bus_addr_t;
+#else
+typedef u32 pci_bus_addr_t;
+#endif
+
struct pci_bus_region {
- dma_addr_t start;
- dma_addr_t end;
+ pci_bus_addr_t start;
+ pci_bus_addr_t end;
};
struct pci_dynids {
@@ -1120,7 +1126,7 @@ int __must_check pci_bus_alloc_resource(
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
-static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
+static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
{
struct pci_bus_region region;
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -139,12 +139,20 @@ typedef unsigned long blkcnt_t;
*/
#define pgoff_t unsigned long
-/* A dma_addr_t can hold any valid DMA or bus address for the platform */
+/*
+ * A dma_addr_t can hold any valid DMA address, i.e., any address returned
+ * by the DMA API.
+ *
+ * If the DMA API only uses 32-bit addresses, dma_addr_t need only be 32
+ * bits wide. Bus addresses, e.g., PCI BARs, may be wider than 32 bits,
+ * but drivers do memory-mapped I/O to ioremapped kernel virtual addresses,
+ * so they don't care about the size of the actual bus addresses.
+ */
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
typedef u64 dma_addr_t;
#else
typedef u32 dma_addr_t;
-#endif /* dma_addr_t */
+#endif
#ifdef __CHECKER__
#else
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Williamson <[email protected]>
commit a5dd4b4b0570b3bf880d563969b245dfbd170c1e upstream.
The commit referenced below deferred waiting for command completion until
the start of the next command, allowing hardware to do the latching
asynchronously. Unfortunately, being ready to accept a new command is the
only indication we have that the previous command is completed. In cases
where we need that state change to be enabled, we must still wait for
completion. For instance, pciehp_reset_slot() attempts to disable anything
that might generate a surprise hotplug on slots that support presence
detection. If we don't wait for those settings to latch before the
secondary bus reset, we negate any value in attempting to prevent the
spurious hotplug.
Create a base function with optional wait and helper functions so that
pcie_write_cmd() turns back into the "safe" interface which waits before
and after issuing a command and add pcie_write_cmd_nowait(), which
eliminates the trailing wait for asynchronous completion. The following
functions are returned to their previous behavior:
pciehp_power_on_slot
pciehp_power_off_slot
pcie_disable_notification
pciehp_reset_slot
The rationale is that pciehp_power_on_slot() enables the link and therefore
relies on completion of power-on. pciehp_power_off_slot() and
pcie_disable_notification() need a wait because data structures may be
freed after these calls and continued signaling from the device would be
unexpected. And, of course, pciehp_reset_slot() needs to wait for the
scenario outlined above.
Fixes: 3461a068661c ("PCI: pciehp: Wait for hotplug command completion lazily")
Signed-off-by: Alex Williamson <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/pci/hotplug/pciehp_hpc.c | 52 ++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 14 deletions(-)
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -176,20 +176,17 @@ static void pcie_wait_cmd(struct control
jiffies_to_msecs(jiffies - ctrl->cmd_started));
}
-/**
- * pcie_write_cmd - Issue controller command
- * @ctrl: controller to which the command is issued
- * @cmd: command value written to slot control register
- * @mask: bitmask of slot control register to be modified
- */
-static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
+static void pcie_do_write_cmd(struct controller *ctrl, u16 cmd,
+ u16 mask, bool wait)
{
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_ctrl;
mutex_lock(&ctrl->ctrl_lock);
- /* Wait for any previous command that might still be in progress */
+ /*
+ * Always wait for any previous command that might still be in progress
+ */
pcie_wait_cmd(ctrl);
pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &slot_ctrl);
@@ -201,9 +198,33 @@ static void pcie_write_cmd(struct contro
ctrl->cmd_started = jiffies;
ctrl->slot_ctrl = slot_ctrl;
+ /*
+ * Optionally wait for the hardware to be ready for a new command,
+ * indicating completion of the above issued command.
+ */
+ if (wait)
+ pcie_wait_cmd(ctrl);
+
mutex_unlock(&ctrl->ctrl_lock);
}
+/**
+ * pcie_write_cmd - Issue controller command
+ * @ctrl: controller to which the command is issued
+ * @cmd: command value written to slot control register
+ * @mask: bitmask of slot control register to be modified
+ */
+static void pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
+{
+ pcie_do_write_cmd(ctrl, cmd, mask, true);
+}
+
+/* Same as above without waiting for the hardware to latch */
+static void pcie_write_cmd_nowait(struct controller *ctrl, u16 cmd, u16 mask)
+{
+ pcie_do_write_cmd(ctrl, cmd, mask, false);
+}
+
bool pciehp_check_link_active(struct controller *ctrl)
{
struct pci_dev *pdev = ctrl_dev(ctrl);
@@ -422,7 +443,7 @@ void pciehp_set_attention_status(struct
default:
return;
}
- pcie_write_cmd(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC);
+ pcie_write_cmd_nowait(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
}
@@ -434,7 +455,8 @@ void pciehp_green_led_on(struct slot *sl
if (!PWR_LED(ctrl))
return;
- pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON, PCI_EXP_SLTCTL_PIC);
+ pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
+ PCI_EXP_SLTCTL_PIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
PCI_EXP_SLTCTL_PWR_IND_ON);
@@ -447,7 +469,8 @@ void pciehp_green_led_off(struct slot *s
if (!PWR_LED(ctrl))
return;
- pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, PCI_EXP_SLTCTL_PIC);
+ pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+ PCI_EXP_SLTCTL_PIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
PCI_EXP_SLTCTL_PWR_IND_OFF);
@@ -460,7 +483,8 @@ void pciehp_green_led_blink(struct slot
if (!PWR_LED(ctrl))
return;
- pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, PCI_EXP_SLTCTL_PIC);
+ pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
+ PCI_EXP_SLTCTL_PIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
PCI_EXP_SLTCTL_PWR_IND_BLINK);
@@ -613,7 +637,7 @@ void pcie_enable_notification(struct con
PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
PCI_EXP_SLTCTL_DLLSCE);
- pcie_write_cmd(ctrl, cmd, mask);
+ pcie_write_cmd_nowait(ctrl, cmd, mask);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
}
@@ -664,7 +688,7 @@ int pciehp_reset_slot(struct slot *slot,
pci_reset_bridge_secondary_bus(ctrl->pcie->port);
pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, stat_mask);
- pcie_write_cmd(ctrl, ctrl_mask, ctrl_mask);
+ pcie_write_cmd_nowait(ctrl, ctrl_mask, ctrl_mask);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, ctrl_mask);
if (pciehp_poll_mode)
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhichang Yuan <[email protected]>
commit 5dbb4c6167229c8d4f528e8ec26699a7305000a3 upstream.
41f8bba7f555 ("of/pci: Add pci_register_io_range() and
pci_pio_to_address()") added support for systems with several I/O ranges
described by OF bindings. It modified pci_address_to_pio() look up the
io_range for a given CPU physical address, but the conversion was wrong.
Fix the conversion of address to I/O port.
[bhelgaas: changelog]
Fixes: 41f8bba7f555 ("of/pci: Add pci_register_io_range() and pci_pio_to_address()")
Signed-off-by: Zhichang Yuan <[email protected]>
Signed-off-by: Bjorn Helgaas <[email protected]>
Acked-by: Liviu Dudau <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/of/address.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -765,7 +765,7 @@ unsigned long __weak pci_address_to_pio(
spin_lock(&io_range_lock);
list_for_each_entry(res, &io_range_list, list) {
if (address >= res->start && address < res->start + res->size) {
- addr = res->start - address + offset;
+ addr = address - res->start + offset;
break;
}
offset += res->size;
4.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frodo Lai <[email protected]>
commit 469d7d22cea146e40efe8c330e5164b4d8f13934 upstream.
The i2c_master_recv() uses readsize to receive data from i2c but compares
to size of rdbuf which is always 27. This would cause problem when the
max_fingers is not 5. Change the comparison value to readsize instead.
Fixes: 36874c7e219 ("Input: pixcir_i2c_ts - support up to 5 fingers and
hardware tracking IDs:)
Signed-off-by: Frodo Lai <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/input/touchscreen/pixcir_i2c_ts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/input/touchscreen/pixcir_i2c_ts.c
+++ b/drivers/input/touchscreen/pixcir_i2c_ts.c
@@ -78,7 +78,7 @@ static void pixcir_ts_parse(struct pixci
}
ret = i2c_master_recv(tsdata->client, rdbuf, readsize);
- if (ret != sizeof(rdbuf)) {
+ if (ret != readsize) {
dev_err(&tsdata->client->dev,
"%s: i2c_master_recv failed(), ret=%d\n",
__func__, ret);
On 07/19/2015 12:10 PM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.0.9 release.
> There are 58 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> Anything received after that time might be too late.
>
Build results:
total: 124 pass: 124 fail: 0
Qemu test results:
total: 30 pass: 30 fail: 0
Details are available at http://server.roeck-us.net:8010/builders/
Guenter
On Sun, Jul 19, 2015 at 12:10:38PM -0700, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.0.9 release.
> There are 58 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> Anything received after that time might be too late.
Compiled and booted on x86_32. No errors in dmesg.
regards
sudip
On 07/19/2015 01:10 PM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.0.9 release.
> There are 58 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.0.9-rc1.gz
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
[email protected] | (970) 217-8978
On Sunday, July 19, 2015 12:10:38 PM Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.0.9 release.
> There are 58 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> Anything received after that time might be too late.
Can you please add commit 0294112ee313 (ACPI / PNP: Reserve ACPI resources
at the fs_initcall_sync stage) to this series too?
It fixes an exsiting regression in earlier 4.0.y.
Thanks,
Rafael
On Mon, Jul 20, 2015 at 11:29:28PM +0200, Rafael J. Wysocki wrote:
> On Sunday, July 19, 2015 12:10:38 PM Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.0.9 release.
> > There are 58 patches in this series, all will be posted as a response
> > to this one. If anyone has any issues with these being applied, please
> > let me know.
> >
> > Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> > Anything received after that time might be too late.
>
> Can you please add commit 0294112ee313 (ACPI / PNP: Reserve ACPI resources
> at the fs_initcall_sync stage) to this series too?
>
> It fixes an exsiting regression in earlier 4.0.y.
How about I wait for the next 4.0.y, which will be out later this week,
as it would be good for people to be able to test this patch out well.
thanks,
greg k-h
On Monday, July 20, 2015 03:04:06 PM Greg Kroah-Hartman wrote:
> On Mon, Jul 20, 2015 at 11:29:28PM +0200, Rafael J. Wysocki wrote:
> > On Sunday, July 19, 2015 12:10:38 PM Greg Kroah-Hartman wrote:
> > > This is the start of the stable review cycle for the 4.0.9 release.
> > > There are 58 patches in this series, all will be posted as a response
> > > to this one. If anyone has any issues with these being applied, please
> > > let me know.
> > >
> > > Responses should be made by Tue Jul 21 19:08:01 UTC 2015.
> > > Anything received after that time might be too late.
> >
> > Can you please add commit 0294112ee313 (ACPI / PNP: Reserve ACPI resources
> > at the fs_initcall_sync stage) to this series too?
> >
> > It fixes an exsiting regression in earlier 4.0.y.
>
> How about I wait for the next 4.0.y, which will be out later this week,
> as it would be good for people to be able to test this patch out well.
Yes, that should work too.
Thanks,
Rafael
Greg,
The kernel still does not compile with gcc-4.5.1 since linux-4.0.5 when
a kvm back-port from 4.1-rc5 went in. (This is on Linux 4.1.2 SMP Mon
Jul 13 18:08:30 EDT 2015 x86_64 Fedora 14)
This mis-compile was fixed in 4.1-rc8. The diff was:
diff -ur linux-4.1-rc7/arch/x86/kvm/mmu.c
linux-4.1-rc8/arch/x86/kvm/mmu.c
--- linux-4.1-rc7/arch/x86/kvm/mmu.c 2015-07-15 00:05:34.000000000 -0400
+++ linux-4.1-rc8/arch/x86/kvm/mmu.c 2015-07-15 00:07:45.000000000 -0400
@@ -4215,13 +4215,13 @@
u64 entry, gentry, *spte;
int npte;
bool remote_flush, local_flush, zap_page;
- union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
- .cr0_wp = 1,
- .cr4_pae = 1,
- .nxe = 1,
- .smep_andnot_wp = 1,
- .smap_andnot_wp = 1,
- };
+ union kvm_mmu_page_role mask = { };
+
+ mask.cr0_wp = 1;
+ mask.cr4_pae = 1;
+ mask.nxe = 1;
+ mask.smep_andnot_wp = 1;
+ mask.smap_andnot_wp = 1;
/*
* If we don't have indirect shadow pages, it means no page is
Please add to linux-4.0.9 so older compilers will work.
Thanks,
Don Parsons
PS: Compile error is :
CC [M] arch/x86/kvm/mmu.o
arch/x86/kvm/mmu.c: In function kvm_mmu_pte_write:
arch/x86/kvm/mmu.c:4219:3: error: unknown field cr0_wp specified
in initializer
arch/x86/kvm/mmu.c:4220:3: error: unknown field cr4_pae specified
in initializer
arch/x86/kvm/mmu.c:4220:3: warning: excess elements in union initializer
arch/x86/kvm/mmu.c:4220:3: warning: (near initialization for
(anonymous))
arch/x86/kvm/mmu.c:4221:3: error: unknown field nxe specified in
initializer
arch/x86/kvm/mmu.c:4221:3: warning: excess elements in union initializer
arch/x86/kvm/mmu.c:4221:3: warning: (near initialization for
(anonymous))
arch/x86/kvm/mmu.c:4222:3: error: unknown field smep_andnot_wp
specified in initializer
arch/x86/kvm/mmu.c:4222:3: warning: excess elements in union initializer
arch/x86/kvm/mmu.c:4222:3: warning: (near initialization for
(anonymous))
arch/x86/kvm/mmu.c:4223:3: error: unknown field smap_andnot_wp
specified in initializer
arch/x86/kvm/mmu.c:4223:3: warning: excess elements in union initializer
arch/x86/kvm/mmu.c:4223:3: warning: (near initialization for
(anonymous))
make[2]: *** [arch/x86/kvm/mmu.o] Error 1
make[1]: *** [arch/x86/kvm] Error 2
make: *** [arch/x86] Error 2
On Tue, Jul 21, 2015 at 01:13:27PM -0400, Donald Parsons wrote:
> Greg,
>
> The kernel still does not compile with gcc-4.5.1 since linux-4.0.5 when
> a kvm back-port from 4.1-rc5 went in. (This is on Linux 4.1.2 SMP Mon
> Jul 13 18:08:30 EDT 2015 x86_64 Fedora 14)
>
> This mis-compile was fixed in 4.1-rc8. The diff was:
>
> diff -ur linux-4.1-rc7/arch/x86/kvm/mmu.c
> linux-4.1-rc8/arch/x86/kvm/mmu.c
> --- linux-4.1-rc7/arch/x86/kvm/mmu.c 2015-07-15 00:05:34.000000000 -0400
> +++ linux-4.1-rc8/arch/x86/kvm/mmu.c 2015-07-15 00:07:45.000000000 -0400
> @@ -4215,13 +4215,13 @@
> u64 entry, gentry, *spte;
> int npte;
> bool remote_flush, local_flush, zap_page;
> - union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
> - .cr0_wp = 1,
> - .cr4_pae = 1,
> - .nxe = 1,
> - .smep_andnot_wp = 1,
> - .smap_andnot_wp = 1,
> - };
> + union kvm_mmu_page_role mask = { };
> +
> + mask.cr0_wp = 1;
> + mask.cr4_pae = 1;
> + mask.nxe = 1;
> + mask.smep_andnot_wp = 1;
> + mask.smap_andnot_wp = 1;
>
> /*
> * If we don't have indirect shadow pages, it means no page is
>
>
> Please add to linux-4.0.9 so older compilers will work.
What is the commit id in Linus's tree that resolves this?
thanks,
greg k-h
On Tue, 2015-07-21 at 11:13 -0700, Greg Kroah-Hartman wrote:
> On Tue, Jul 21, 2015 at 01:13:27PM -0400, Donald Parsons wrote:
> > Greg,
> >
> > The kernel still does not compile with gcc-4.5.1 since linux-4.0.5 when
> > a kvm back-port from 4.1-rc5 went in. (This is on Linux 4.1.2 SMP Mon
> > Jul 13 18:08:30 EDT 2015 x86_64 Fedora 14)
> >
> > This mis-compile was fixed in 4.1-rc8. The diff was:
> >
> > diff -ur linux-4.1-rc7/arch/x86/kvm/mmu.c
> > linux-4.1-rc8/arch/x86/kvm/mmu.c
> > --- linux-4.1-rc7/arch/x86/kvm/mmu.c 2015-07-15 00:05:34.000000000 -0400
> > +++ linux-4.1-rc8/arch/x86/kvm/mmu.c 2015-07-15 00:07:45.000000000 -0400
> > @@ -4215,13 +4215,13 @@
> > u64 entry, gentry, *spte;
> > int npte;
> > bool remote_flush, local_flush, zap_page;
> > - union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
> > - .cr0_wp = 1,
> > - .cr4_pae = 1,
> > - .nxe = 1,
> > - .smep_andnot_wp = 1,
> > - .smap_andnot_wp = 1,
> > - };
> > + union kvm_mmu_page_role mask = { };
> > +
> > + mask.cr0_wp = 1;
> > + mask.cr4_pae = 1;
> > + mask.nxe = 1;
> > + mask.smep_andnot_wp = 1;
> > + mask.smap_andnot_wp = 1;
> >
> > /*
> > * If we don't have indirect shadow pages, it means no page is
> >
> >
> > Please add to linux-4.0.9 so older compilers will work.
>
> What is the commit id in Linus's tree that resolves this?
I do not know but I found this in Linus' linux-4.1-rc8 email announce:
Andrew Morton (1):
arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
which must be it. Added Andrew to cc as he hopefully knows the answer
to your question.
Thanks,
Don Parsons
On Tue, Jul 21, 2015 at 05:02:31PM -0400, Donald Parsons wrote:
> On Tue, 2015-07-21 at 11:13 -0700, Greg Kroah-Hartman wrote:
> > On Tue, Jul 21, 2015 at 01:13:27PM -0400, Donald Parsons wrote:
> > > Greg,
> > >
> > > The kernel still does not compile with gcc-4.5.1 since linux-4.0.5 when
> > > a kvm back-port from 4.1-rc5 went in. (This is on Linux 4.1.2 SMP Mon
> > > Jul 13 18:08:30 EDT 2015 x86_64 Fedora 14)
> > >
> > > This mis-compile was fixed in 4.1-rc8. The diff was:
> > >
> > > diff -ur linux-4.1-rc7/arch/x86/kvm/mmu.c
> > > linux-4.1-rc8/arch/x86/kvm/mmu.c
> > > --- linux-4.1-rc7/arch/x86/kvm/mmu.c 2015-07-15 00:05:34.000000000 -0400
> > > +++ linux-4.1-rc8/arch/x86/kvm/mmu.c 2015-07-15 00:07:45.000000000 -0400
> > > @@ -4215,13 +4215,13 @@
> > > u64 entry, gentry, *spte;
> > > int npte;
> > > bool remote_flush, local_flush, zap_page;
> > > - union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
> > > - .cr0_wp = 1,
> > > - .cr4_pae = 1,
> > > - .nxe = 1,
> > > - .smep_andnot_wp = 1,
> > > - .smap_andnot_wp = 1,
> > > - };
> > > + union kvm_mmu_page_role mask = { };
> > > +
> > > + mask.cr0_wp = 1;
> > > + mask.cr4_pae = 1;
> > > + mask.nxe = 1;
> > > + mask.smep_andnot_wp = 1;
> > > + mask.smap_andnot_wp = 1;
> > >
> > > /*
> > > * If we don't have indirect shadow pages, it means no page is
> > >
> > >
> > > Please add to linux-4.0.9 so older compilers will work.
> >
> > What is the commit id in Linus's tree that resolves this?
>
> I do not know but I found this in Linus' linux-4.1-rc8 email announce:
>
> Andrew Morton (1):
> arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
>
> which must be it. Added Andrew to cc as he hopefully knows the answer
> to your question.
You can dig through git to find it pretty easily...
Anyway, given that the 4.0 release I'm doing at the moment is the last
one, and it's end-of-life, this is a bit late and isn't going to matter
much. People should be on 4.1 already.
thanks,
greg k-h
On Tue, 2015-07-21 at 14:10 -0700, Greg Kroah-Hartman wrote:
> > Andrew Morton (1):
> > arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
> >
> > which must be it. Added Andrew to cc as he hopefully knows the
> answer to your question.
>
> You can dig through git to find it pretty easily...
>
> Anyway, given that the 4.0 release I'm doing at the moment is the last
> one, and it's end-of-life, this is a bit late and isn't going to
> matter much. People should be on 4.1 already.
Okay. But just in case. I had to learn about git and do a checkout.
git log v4.1-rc8 arch/x86/kvm/mmu.c shows:
commit 5ec45a192fe6e287f0fc06d5ca4f3bd446d94803
Author: Andrew Morton <[email protected]>
Date: Wed Jun 10 11:15:02 2015 -0700
arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
Fix this compile issue with gcc-4.4.4:
arch/x86/kvm/mmu.c: In function 'kvm_mmu_pte_write':
arch/x86/kvm/mmu.c:4256: error: unknown field 'cr0_wp' specified
in initializer
arch/x86/kvm/mmu.c:4257: error: unknown field 'cr4_pae' specified
in initializer
arch/x86/kvm/mmu.c:4257: warning: excess elements in union
initializer
...
gcc-4.4.4 (at least) has issues when using anonymous unions in
initializers.
Fixes: edc90b7dc4ceef6 ("KVM: MMU: fix SMAP virtualization")
Cc: Xiao Guangrong <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Davidlohr Bueso <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Hopefully commit 5ec45a192fe6e287f0fc06d5ca4f3bd446d94803
is what you were looking for. If not, very sorry for interrupting you.
Thanks,
Don
On Tue, Jul 21, 2015 at 06:14:06PM -0400, Donald Parsons wrote:
> On Tue, 2015-07-21 at 14:10 -0700, Greg Kroah-Hartman wrote:
> > > Andrew Morton (1):
> > > arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
> > >
> > > which must be it. Added Andrew to cc as he hopefully knows the
> > answer to your question.
> >
> > You can dig through git to find it pretty easily...
> >
> > Anyway, given that the 4.0 release I'm doing at the moment is the last
> > one, and it's end-of-life, this is a bit late and isn't going to
> > matter much. People should be on 4.1 already.
>
> Okay. But just in case. I had to learn about git and do a checkout.
>
> git log v4.1-rc8 arch/x86/kvm/mmu.c shows:
>
> commit 5ec45a192fe6e287f0fc06d5ca4f3bd446d94803
> Author: Andrew Morton <[email protected]>
> Date: Wed Jun 10 11:15:02 2015 -0700
>
> arch/x86/kvm/mmu.c: work around gcc-4.4.4 bug
>
> Fix this compile issue with gcc-4.4.4:
>
> arch/x86/kvm/mmu.c: In function 'kvm_mmu_pte_write':
> arch/x86/kvm/mmu.c:4256: error: unknown field 'cr0_wp' specified
> in initializer
> arch/x86/kvm/mmu.c:4257: error: unknown field 'cr4_pae' specified
> in initializer
> arch/x86/kvm/mmu.c:4257: warning: excess elements in union
> initializer
> ...
>
> gcc-4.4.4 (at least) has issues when using anonymous unions in
> initializers.
>
> Fixes: edc90b7dc4ceef6 ("KVM: MMU: fix SMAP virtualization")
> Cc: Xiao Guangrong <[email protected]>
> Cc: Paolo Bonzini <[email protected]>
> Cc: Davidlohr Bueso <[email protected]>
> Signed-off-by: Andrew Morton <[email protected]>
> Signed-off-by: Linus Torvalds <[email protected]>
>
>
> Hopefully commit 5ec45a192fe6e287f0fc06d5ca4f3bd446d94803
> is what you were looking for. If not, very sorry for interrupting you.
Thanks, that's exactly what I needed. I've queued it up, in the
off-chance that there would be another 4.0-stable kernel, but I don't
think there will be. Please move to 4.1 at this point in time.
thanks,
greg k-h