This is the start of the stable review cycle for the 3.12.58 release.
There are 98 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 Wed Apr 13 15:21:57 CEST 2016.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.58-rc1.xz
and the diffstat can be found below.
thanks,
js
===============
Aaro Koskinen (1):
mtd: onenand: fix deadlock in onenand_block_markbad
Alan Stern (1):
USB: fix invalid memory access in hub_activate()
Andi Kleen (1):
perf/x86/intel: Fix PEBS data source interpretation on
Nehalem/Westmere
Andy Lutomirski (2):
x86/iopl/64: Properly context-switch IOPL on Xen PV
x86/iopl: Fix iopl capability check on Xen PV
Aurelien Jacquiot (1):
rapidio/rionet: fix deadlock on SMP
Benjamin Poirier (1):
mld, igmp: Fix reserved tailroom calculation
Bjorn Helgaas (1):
PCI: Disable IO/MEM decoding for devices with non-compliant BARs
Bjørn Mork (1):
USB: option: add "D-Link DWM-221 B1" device id
[email protected] (1):
ahci: Add Device ID for Intel Sunrise Point PCH
Christian Borntraeger (1):
kernel: Provide READ_ONCE and ASSIGN_ONCE
Dan Carpenter (1):
EDAC, amd64_edac: Shift wrapping issue in f1x_get_norm_dct_addr()
Daniel Borkmann (1):
ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs
Dave Jones (1):
x86/apic: Fix suspicious RCU usage in
smp_trace_call_function_interrupt()
David S. Miller (1):
ipv4: Don't do expensive useless work during inetdev destroy.
David Vrabel (3):
xen: Add RING_COPY_REQUEST()
xen-netback: don't use last request to determine minimum Tx credit
xen-netback: use RING_COPY_REQUEST() throughout
Dirk Brandewie (1):
intel_pstate: Use del_timer_sync in intel_pstate_cpu_stop
Dmitry Tunin (4):
Bluetooth: btusb: Add new AR3012 ID 13d3:3395
Bluetooth: btusb: Add a new AR3012 ID 04ca:3014
Bluetooth: btusb: Add a new AR3012 ID 13d3:3472
Bluetooth: Add new AR3012 ID 0489:e095
Douglas Gilbert (1):
sg: fix dxferp in from_to case
Eric Sandeen (1):
xfs: allow inode allocations in post-growfs disk space
Eric W. Biederman (1):
umount: Do not allow unmounting rootfs.
Eric Wheeler (1):
bcache: fix cache_set_flush() NULL pointer dereference on OOM
Gabriel Krisman Bertazi (1):
ipr: Fix regression when loading firmware
Hans Verkuil (1):
adv7511: TX_EDID_PRESENT is still 1 after a disconnect
Hans de Goede (3):
pwc: Add USB id for Philips Spc880nc webcam
saa7134: Fix bytesperline not being set correctly for planar formats
bttv: Width must be a multiple of 16 when capturing planar formats
Himanshu Madhani (1):
target: Fix target_release_cmd_kref shutdown comp leak
Ian Mitchell (1):
Fix kmalloc overflow in LPFC driver at large core count
Insu Yun (1):
ipr: Fix out-of-bounds null overwrite
Jann Horn (1):
fs/coredump: prevent fsuid=0 dumps into user-controlled directories
Jeff Layton (1):
nfs: fix high load average due to callback thread sleeping
Jes Sorensen (1):
md/raid5: Compare apples to apples (or sectors to sectors)
Jiri Kosina (1):
kbuild/mkspec: fix grub2 installkernel issue
Jiri Olsa (1):
perf/x86/intel: Use PAGE_SIZE for PEBS buffer size on Core2
Jiri Slaby (1):
net/ipv6: fix DEVCONF_ constants
Johan Hovold (1):
USB: visor: fix null-deref at probe
John Allen (1):
drivers/base/memory.c: fix kernel warning during memory hotplug on
ppc64
Joseph Qi (2):
ocfs2/dlm: fix race between convert and recovery
ocfs2/dlm: fix BUG in dlm_move_lockres_to_recovery_list
Josh Boyer (3):
USB: iowarrior: fix oops with malicious USB descriptors
USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices
Input: powermate - fix oops with malicious USB descriptors
Julia Lawall (1):
scripts/coccinelle: modernize &
Kirill Tkhai (1):
sched: Fix race between task_group and sched_task_group
Konrad Rzeszutek Wilk (2):
xen/pciback: Save xen_pci_op commands before processing it
xen/pciback: Save the number of MSI-X entries to be copied later.
Lukasz Odzioba (1):
hwmon: (coretemp) Increase limit of maximum core ID from 32 to 128.
Mario Kleiner (1):
drm/radeon: Don't drop DP 2.7 Ghz link setup on some cards.
Markus Metzger (1):
perf, nmi: Fix unknown NMI warning
Martin Schwidefsky (1):
s390/mm: four page table levels vs. fork
Martyn Welch (1):
USB: serial: cp210x: Adding GE Healthcare Device ID
Mateusz Guzik (1):
xfs: fix two memory leaks in xfs_attr_list.c error paths
Maurizio Lombardi (1):
be2iscsi: set the boot_kset pointer to NULL in case of failure
Max Filippov (2):
xtensa: ISS: don't hang if stdin EOF is reached
xtensa: clear all DBREAKC registers on start
Michael S. Tsirkin (1):
watchdog: rc32434_wdt: fix ioctl error handling
Michal Hocko (1):
memcg: do not hang on OOM when killed by userspace OOM access to
memory reserves
OGAWA Hirofumi (1):
jbd2: fix FS corruption possibility in jbd2_journal_destroy() on
umount path
Oliver Neukum (8):
usb: retry reset if a device times out
usb: hub: fix a typo in hub_port_init() leading to wrong logic
USB: cdc-acm: more sanity checking
USB: usb_driver_claim_interface: add sanity checking
USB: mct_u232: add sanity checking in probe
USB: digi_acceleport: do sanity checking for the number of ports
USB: cypress_m8: add endpoint sanity check
Input: ims-pcu - sanity check against missing interfaces
Paolo Bonzini (2):
KVM: fix spin_lock_init order on x86
KVM: VMX: avoid guest hang on invalid invept instruction
Peter Hurley (1):
net: irda: Fix use-after-free in irtty_open()
Rabin Vincent (1):
splice: handle zero nr_pages in splice_to_pipe()
Radim Krčmář (1):
KVM: i8254: change PIT discard tick policy
Raghava Aditya Renukunta (1):
aacraid: Fix memory leak in aac_fib_map_free
Roger Pau Monné (2):
xen-blkback: only read request operation from shared ring once
xen-blkback: read from indirect descriptors only once
Sebastian Frias (1):
8250: use callbacks to access UART_DLL/UART_DLM
Steven Rostedt (Red Hat) (3):
tracing: Have preempt(irqs)off trace preempt disabled functions
tracing: Fix crash from reading trace_pipe with sendfile
tracing: Fix trace_printk() to print when not using bprintk()
Takashi Iwai (6):
ALSA: rawmidi: Make snd_rawmidi_transmit() race-free
ALSA: seq: Fix leak of pool buffer at concurrent writes
ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk()
ALSA: usb-audio: Add sanity checks for endpoint accesses
ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()
ALSA: hda - Fix unconditional GPIO toggle via automute
Thomas Gleixner (1):
sched/cputime: Fix steal time accounting vs. CPU hotplug
Tiffany Lin (1):
media: v4l2-compat-ioctl32: fix missing length copy in
put_v4l2_buffer32
Vittorio Gambaletta (VittGam) (1):
ALSA: intel8x0: Add clock quirk entry for AD1981B on IBM ThinkPad X41.
Vladis Dronov (2):
ALSA: usb-audio: Fix double-free in error paths after
snd_usb_add_audio_stream() call
Input: ati_remote2 - fix crashes on detecting device with invalid
descriptor
Wang Shilong (1):
Btrfs: skip locking when searching commit root
Wei Huang (1):
KVM: SVM: add rdmsr support for AMD event registers
Yuval Mintz (1):
bnx2x: Add new device ids under the Qlogic vendor
arch/s390/include/asm/mmu_context.h | 15 ++--
arch/um/drivers/mconsole_kern.c | 2 +-
arch/x86/include/asm/apic.h | 2 +-
arch/x86/include/asm/xen/hypervisor.h | 2 +
arch/x86/kernel/cpu/perf_event.h | 3 +
arch/x86/kernel/cpu/perf_event_intel.c | 8 +-
arch/x86/kernel/cpu/perf_event_intel_ds.c | 24 +++++-
arch/x86/kernel/ioport.c | 12 ++-
arch/x86/kernel/process_64.c | 12 +++
arch/x86/kvm/i8254.c | 12 +--
arch/x86/kvm/vmx.c | 1 +
arch/x86/kvm/x86.c | 6 ++
arch/x86/xen/enlighten.c | 2 +-
arch/xtensa/kernel/head.S | 2 +-
arch/xtensa/platforms/iss/console.c | 10 ++-
drivers/ata/ahci.c | 2 +
drivers/base/memory.c | 16 ++--
drivers/block/xen-blkback/blkback.c | 15 ++--
drivers/block/xen-blkback/common.h | 8 +-
drivers/bluetooth/ath3k.c | 8 ++
drivers/bluetooth/btusb.c | 4 +
drivers/cpufreq/intel_pstate.c | 2 +-
drivers/edac/amd64_edac.c | 2 +-
drivers/gpu/drm/radeon/atombios_encoders.c | 6 +-
drivers/hwmon/coretemp.c | 2 +-
drivers/input/misc/ati_remote2.c | 36 +++++++--
drivers/input/misc/ims-pcu.c | 4 +
drivers/input/misc/powermate.c | 3 +
drivers/md/bcache/super.c | 3 +
drivers/md/raid5.c | 4 +-
drivers/media/i2c/adv7511.c | 21 +++--
drivers/media/pci/bt8xx/bttv-driver.c | 26 ++++--
drivers/media/pci/saa7134/saa7134-video.c | 18 +++--
drivers/media/usb/pwc/pwc-if.c | 6 ++
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 21 ++---
drivers/mtd/onenand/onenand_base.c | 3 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 +
drivers/net/irda/irtty-sir.c | 10 ---
drivers/net/rionet.c | 4 +-
drivers/net/xen-netback/netback.c | 34 ++++----
drivers/pci/probe.c | 14 ++++
drivers/scsi/aacraid/commsup.c | 9 ++-
drivers/scsi/be2iscsi/be_main.c | 1 +
drivers/scsi/ipr.c | 10 ++-
drivers/scsi/lpfc/lpfc_init.c | 6 +-
drivers/scsi/lpfc/lpfc_sli4.h | 1 -
drivers/scsi/sg.c | 3 +-
drivers/target/target_core_transport.c | 2 -
drivers/tty/serial/8250/8250_core.c | 18 ++---
drivers/usb/class/cdc-acm.c | 3 +
drivers/usb/core/driver.c | 6 +-
drivers/usb/core/hub.c | 39 +++++++--
drivers/usb/misc/iowarrior.c | 6 ++
drivers/usb/serial/cp210x.c | 1 +
drivers/usb/serial/cypress_m8.c | 11 ++-
drivers/usb/serial/digi_acceleport.c | 19 +++++
drivers/usb/serial/ftdi_sio.c | 4 +
drivers/usb/serial/ftdi_sio_ids.h | 8 ++
drivers/usb/serial/mct_u232.c | 9 ++-
drivers/usb/serial/option.c | 2 +
drivers/usb/serial/visor.c | 5 ++
drivers/watchdog/rc32434_wdt.c | 2 +-
drivers/xen/xen-pciback/pciback.h | 1 +
drivers/xen/xen-pciback/pciback_ops.c | 19 ++++-
fs/btrfs/backref.c | 4 +-
fs/coredump.c | 30 ++++++-
fs/fhandle.c | 2 +-
fs/jbd2/journal.c | 17 ++--
fs/namespace.c | 1 +
fs/nfs/callback.c | 6 +-
fs/ocfs2/dlm/dlmconvert.c | 24 +++++-
fs/ocfs2/dlm/dlmrecovery.c | 1 -
fs/open.c | 6 +-
fs/splice.c | 3 +
fs/xfs/xfs_attr_list.c | 19 ++---
fs/xfs/xfs_mount.c | 4 +-
fs/xfs/xfs_super.c | 20 +++--
fs/xfs/xfs_super.h | 4 +-
include/linux/compiler.h | 74 +++++++++++++++++
include/linux/fs.h | 2 +-
include/linux/kernel.h | 6 +-
include/linux/pci.h | 1 +
include/linux/skbuff.h | 24 ++++++
include/sound/rawmidi.h | 4 +
include/uapi/linux/ipv6.h | 4 +
include/xen/interface/io/ring.h | 14 ++++
kernel/sched/core.c | 7 ++
kernel/sched/sched.h | 13 +++
kernel/sysctl_binary.c | 2 +-
kernel/trace/trace.c | 5 +-
kernel/trace/trace_irqsoff.c | 8 +-
kernel/trace/trace_printk.c | 3 +
mm/memcontrol.c | 3 +-
net/ipv4/devinet.c | 4 +
net/ipv4/fib_frontend.c | 4 +
net/ipv4/igmp.c | 10 +--
net/ipv4/netfilter/ipt_MASQUERADE.c | 12 ++-
net/ipv6/mcast.c | 8 +-
net/ipv6/netfilter/ip6t_MASQUERADE.c | 12 ++-
scripts/coccinelle/iterators/use_after_iter.cocci | 2 +-
scripts/package/mkspec | 8 +-
sound/core/rawmidi.c | 98 +++++++++++++++++------
sound/core/seq/seq_memory.c | 15 ++--
sound/core/seq/seq_virmidi.c | 17 ++--
sound/pci/hda/patch_cirrus.c | 8 +-
sound/pci/intel8x0.c | 1 +
sound/usb/clock.c | 2 +
sound/usb/endpoint.c | 3 +
sound/usb/mixer_quirks.c | 4 +
sound/usb/pcm.c | 2 +
sound/usb/quirks.c | 26 ++++--
sound/usb/stream.c | 6 +-
virt/kvm/kvm_main.c | 21 ++---
113 files changed, 850 insertions(+), 297 deletions(-)
--
2.8.1
From: Konrad Rzeszutek Wilk <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d159457b84395927b5a52adb72f748dd089ad5e5 upstream.
Commit 8135cf8b092723dbfcc611fe6fdcb3a36c9951c5 (xen/pciback: Save
xen_pci_op commands before processing it) broke enabling MSI-X because
it would never copy the resulting vectors into the response. The
number of vectors requested was being overwritten by the return value
(typically zero for success).
Save the number of vectors before processing the op, so the correct
number of vectors are copied afterwards.
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Reviewed-by: Jan Beulich <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Cc: "Jan Beulich" <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/xen/xen-pciback/pciback_ops.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index a2da466d2333..69f0d4d1d8b7 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -333,6 +333,9 @@ void xen_pcibk_do_op(struct work_struct *data)
struct xen_pcibk_dev_data *dev_data = NULL;
struct xen_pci_op *op = &pdev->op;
int test_intx = 0;
+#ifdef CONFIG_PCI_MSI
+ unsigned int nr = 0;
+#endif
*op = pdev->sh_info->op;
barrier();
@@ -361,6 +364,7 @@ void xen_pcibk_do_op(struct work_struct *data)
op->err = xen_pcibk_disable_msi(pdev, dev, op);
break;
case XEN_PCI_OP_enable_msix:
+ nr = op->value;
op->err = xen_pcibk_enable_msix(pdev, dev, op);
break;
case XEN_PCI_OP_disable_msix:
@@ -383,7 +387,7 @@ void xen_pcibk_do_op(struct work_struct *data)
if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
unsigned int i;
- for (i = 0; i < op->value; i++)
+ for (i = 0; i < nr; i++)
pdev->sh_info->op.msix_entries[i].vector =
op->msix_entries[i].vector;
}
--
2.8.1
From: Jann Horn <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 378c6520e7d29280f400ef2ceaf155c86f05a71a upstream.
This commit fixes the following security hole affecting systems where
all of the following conditions are fulfilled:
- The fs.suid_dumpable sysctl is set to 2.
- The kernel.core_pattern sysctl's value starts with "/". (Systems
where kernel.core_pattern starts with "|/" are not affected.)
- Unprivileged user namespace creation is permitted. (This is
true on Linux >=3.8, but some distributions disallow it by
default using a distro patch.)
Under these conditions, if a program executes under secure exec rules,
causing it to run with the SUID_DUMP_ROOT flag, then unshares its user
namespace, changes its root directory and crashes, the coredump will be
written using fsuid=0 and a path derived from kernel.core_pattern - but
this path is interpreted relative to the root directory of the process,
allowing the attacker to control where a coredump will be written with
root privileges.
To fix the security issue, always interpret core_pattern for dumps that
are written under SUID_DUMP_ROOT relative to the root directory of init.
Signed-off-by: Jann Horn <[email protected]>
Acked-by: Kees Cook <[email protected]>
Cc: Al Viro <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Oleg Nesterov <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/um/drivers/mconsole_kern.c | 2 +-
fs/coredump.c | 30 ++++++++++++++++++++++++++----
fs/fhandle.c | 2 +-
fs/open.c | 6 ++----
include/linux/fs.h | 2 +-
kernel/sysctl_binary.c | 2 +-
6 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 3df3bd544492..1768d4083f74 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -133,7 +133,7 @@ void mconsole_proc(struct mc_request *req)
ptr += strlen("proc");
ptr = skip_spaces(ptr);
- file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
+ file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0);
if (IS_ERR(file)) {
mconsole_reply(req, "Failed to open file", 1, 0);
printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
diff --git a/fs/coredump.c b/fs/coredump.c
index ff78d9075316..86753db01f2d 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -32,6 +32,9 @@
#include <linux/pipe_fs_i.h>
#include <linux/oom.h>
#include <linux/compat.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/path.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
@@ -614,6 +617,8 @@ void do_coredump(siginfo_t *siginfo)
}
} else {
struct inode *inode;
+ int open_flags = O_CREAT | O_RDWR | O_NOFOLLOW |
+ O_LARGEFILE | O_EXCL;
if (cprm.limit < binfmt->min_coredump)
goto fail_unlock;
@@ -652,10 +657,27 @@ void do_coredump(siginfo_t *siginfo)
* what matters is that at least one of the two processes
* writes its coredump successfully, not which one.
*/
- cprm.file = filp_open(cn.corename,
- O_CREAT | 2 | O_NOFOLLOW |
- O_LARGEFILE | O_EXCL,
- 0600);
+ if (need_suid_safe) {
+ /*
+ * Using user namespaces, normal user tasks can change
+ * their current->fs->root to point to arbitrary
+ * directories. Since the intention of the "only dump
+ * with a fully qualified path" rule is to control where
+ * coredumps may be placed using root privileges,
+ * current->fs->root must not be used. Instead, use the
+ * root directory of init_task.
+ */
+ struct path root;
+
+ task_lock(&init_task);
+ get_fs_root(init_task.fs, &root);
+ task_unlock(&init_task);
+ cprm.file = file_open_root(root.dentry, root.mnt,
+ cn.corename, open_flags, 0600);
+ path_put(&root);
+ } else {
+ cprm.file = filp_open(cn.corename, open_flags, 0600);
+ }
if (IS_ERR(cprm.file))
goto fail_unlock;
diff --git a/fs/fhandle.c b/fs/fhandle.c
index d59712dfa3e7..ca3c3dd01789 100644
--- a/fs/fhandle.c
+++ b/fs/fhandle.c
@@ -228,7 +228,7 @@ long do_handle_open(int mountdirfd,
path_put(&path);
return fd;
}
- file = file_open_root(path.dentry, path.mnt, "", open_flag);
+ file = file_open_root(path.dentry, path.mnt, "", open_flag, 0);
if (IS_ERR(file)) {
put_unused_fd(fd);
retval = PTR_ERR(file);
diff --git a/fs/open.c b/fs/open.c
index fc9c0ceed464..3827b632d713 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -923,14 +923,12 @@ struct file *filp_open(const char *filename, int flags, umode_t mode)
EXPORT_SYMBOL(filp_open);
struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
- const char *filename, int flags)
+ const char *filename, int flags, umode_t mode)
{
struct open_flags op;
- int err = build_open_flags(flags, 0, &op);
+ int err = build_open_flags(flags, mode, &op);
if (err)
return ERR_PTR(err);
- if (flags & O_CREAT)
- return ERR_PTR(-EINVAL);
if (!filename && (flags & O_DIRECTORY))
if (!dentry->d_inode->i_op->lookup)
return ERR_PTR(-ENOTDIR);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 042b61b7a2ad..1d106873e7ba 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2005,7 +2005,7 @@ extern long do_sys_open(int dfd, const char __user *filename, int flags,
extern struct file *file_open_name(struct filename *, int, umode_t);
extern struct file *filp_open(const char *, int, umode_t);
extern struct file *file_open_root(struct dentry *, struct vfsmount *,
- const char *, int);
+ const char *, int, umode_t);
extern struct file * dentry_open(const struct path *, int, const struct cred *);
extern int filp_close(struct file *, fl_owner_t id);
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
index b609213ca9a2..7f95a544abab 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -1320,7 +1320,7 @@ static ssize_t binary_sysctl(const int *name, int nlen,
}
mnt = task_active_pid_ns(current)->proc_mnt;
- file = file_open_root(mnt->mnt_root, mnt, pathname, flags);
+ file = file_open_root(mnt->mnt_root, mnt, pathname, flags, 0);
result = PTR_ERR(file);
if (IS_ERR(file))
goto out_putname;
--
2.8.1
From: OGAWA Hirofumi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c0a2ad9b50dd80eeccd73d9ff962234590d5ec93 upstream.
On umount path, jbd2_journal_destroy() writes latest transaction ID
(->j_tail_sequence) to be used at next mount.
The bug is that ->j_tail_sequence is not holding latest transaction ID
in some cases. So, at next mount, there is chance to conflict with
remaining (not overwritten yet) transactions.
mount (id=10)
write transaction (id=11)
write transaction (id=12)
umount (id=10) <= the bug doesn't write latest ID
mount (id=10)
write transaction (id=11)
crash
mount
[recovery process]
transaction (id=11)
transaction (id=12) <= valid transaction ID, but old commit
must not replay
Like above, this bug become the cause of recovery failure, or FS
corruption.
So why ->j_tail_sequence doesn't point latest ID?
Because if checkpoint transactions was reclaimed by memory pressure
(i.e. bdev_try_to_free_page()), then ->j_tail_sequence is not updated.
(And another case is, __jbd2_journal_clean_checkpoint_list() is called
with empty transaction.)
So in above cases, ->j_tail_sequence is not pointing latest
transaction ID at umount path. Plus, REQ_FLUSH for checkpoint is not
done too.
So, to fix this problem with minimum changes, this patch updates
->j_tail_sequence, and issue REQ_FLUSH. (With more complex changes,
some optimizations would be possible to avoid unnecessary REQ_FLUSH
for example though.)
BTW,
journal->j_tail_sequence =
++journal->j_transaction_sequence;
Increment of ->j_transaction_sequence seems to be unnecessary, but
ext3 does this.
Signed-off-by: OGAWA Hirofumi <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/jbd2/journal.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index e2d9856a015a..2f2fe9c7cd51 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1425,11 +1425,12 @@ out:
/**
* jbd2_mark_journal_empty() - Mark on disk journal as empty.
* @journal: The journal to update.
+ * @write_op: With which operation should we write the journal sb
*
* Update a journal's dynamic superblock fields to show that journal is empty.
* Write updated superblock to disk waiting for IO to complete.
*/
-static void jbd2_mark_journal_empty(journal_t *journal)
+static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
{
journal_superblock_t *sb = journal->j_superblock;
@@ -1447,7 +1448,7 @@ static void jbd2_mark_journal_empty(journal_t *journal)
sb->s_start = cpu_to_be32(0);
read_unlock(&journal->j_state_lock);
- jbd2_write_superblock(journal, WRITE_FUA);
+ jbd2_write_superblock(journal, write_op);
/* Log is no longer empty */
write_lock(&journal->j_state_lock);
@@ -1732,7 +1733,13 @@ int jbd2_journal_destroy(journal_t *journal)
if (journal->j_sb_buffer) {
if (!is_journal_aborted(journal)) {
mutex_lock(&journal->j_checkpoint_mutex);
- jbd2_mark_journal_empty(journal);
+
+ write_lock(&journal->j_state_lock);
+ journal->j_tail_sequence =
+ ++journal->j_transaction_sequence;
+ write_unlock(&journal->j_state_lock);
+
+ jbd2_mark_journal_empty(journal, WRITE_FLUSH_FUA);
mutex_unlock(&journal->j_checkpoint_mutex);
} else
err = -EIO;
@@ -1993,7 +2000,7 @@ int jbd2_journal_flush(journal_t *journal)
* the magic code for a fully-recovered superblock. Any future
* commits of data to the journal will restore the current
* s_start value. */
- jbd2_mark_journal_empty(journal);
+ jbd2_mark_journal_empty(journal, WRITE_FUA);
mutex_unlock(&journal->j_checkpoint_mutex);
write_lock(&journal->j_state_lock);
J_ASSERT(!journal->j_running_transaction);
@@ -2039,7 +2046,7 @@ int jbd2_journal_wipe(journal_t *journal, int write)
if (write) {
/* Lock to make assertions happy... */
mutex_lock(&journal->j_checkpoint_mutex);
- jbd2_mark_journal_empty(journal);
+ jbd2_mark_journal_empty(journal, WRITE_FUA);
mutex_unlock(&journal->j_checkpoint_mutex);
}
--
2.8.1
From: Andi Kleen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e17dc65328057c00db7e1bfea249c8771a78b30b upstream.
Jiri reported some time ago that some entries in the PEBS data source table
in perf do not agree with the SDM. We investigated and the bits
changed for Sandy Bridge, but the SDM was not updated.
perf already implements the bits correctly for Sandy Bridge
and later. This patch patches it up for Nehalem and Westmere.
Signed-off-by: Andi Kleen <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/cpu/perf_event.h | 2 ++
arch/x86/kernel/cpu/perf_event_intel.c | 2 ++
arch/x86/kernel/cpu/perf_event_intel_ds.c | 11 ++++++++++-
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 2ac94333bcfd..82833ed3c1d2 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -688,6 +688,8 @@ void intel_pmu_lbr_init_atom(void);
void intel_pmu_lbr_init_snb(void);
+void intel_pmu_pebs_data_source_nhm(void);
+
int intel_pmu_setup_lbr_filter(struct perf_event *event);
int p4_pmu_init(void);
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index d2080aa4322a..0c8fc76b2d2c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2344,6 +2344,7 @@ __init int intel_pmu_init(void)
intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+ intel_pmu_pebs_data_source_nhm();
x86_add_quirk(intel_nehalem_quirk);
pr_cont("Nehalem events, ");
@@ -2405,6 +2406,7 @@ __init int intel_pmu_init(void)
intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] =
X86_CONFIG(.event=0xb1, .umask=0x3f, .inv=1, .cmask=1);
+ intel_pmu_pebs_data_source_nhm();
pr_cont("Westmere events, ");
break;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index 8ad56b3b0169..1cbc27963f68 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -50,7 +50,8 @@ union intel_x86_pebs_dse {
#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
-static const u64 pebs_data_source[] = {
+/* Version for Sandy Bridge and later */
+static u64 pebs_data_source[] = {
P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */
OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
@@ -69,6 +70,14 @@ static const u64 pebs_data_source[] = {
OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
};
+/* Patch up minor differences in the bits */
+void __init intel_pmu_pebs_data_source_nhm(void)
+{
+ pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT);
+ pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
+ pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
+}
+
static u64 precise_store_data(u64 status)
{
union intel_x86_pebs_dse dse;
--
2.8.1
From: Jiri Olsa <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e72daf3f4d764c47fb71c9bdc7f9c54a503825b1 upstream.
Using PAGE_SIZE buffers makes the WRMSR to PERF_GLOBAL_CTRL in
intel_pmu_enable_all() mysteriously hang on Core2. As a workaround, we
don't do this.
The hard lockup is easily triggered by running 'perf test attr'
repeatedly. Most of the time it gets stuck on sample session with
small periods.
# perf test attr -vv
14: struct perf_event_attr setup :
--- start ---
...
'PERF_TEST_ATTR=/tmp/tmpuEKz3B /usr/bin/perf record -o /tmp/tmpuEKz3B/perf.data -c 123 kill >/dev/null 2>&1' ret 1
Reported-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Jiri Olsa <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Andi Kleen <[email protected]>
Cc: Alexander Shishkin <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Kan Liang <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Vince Weaver <[email protected]>
Cc: Wang Nan <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/cpu/perf_event.h | 1 +
arch/x86/kernel/cpu/perf_event_intel_ds.c | 13 +++++++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 53bd2726f4cd..2ac94333bcfd 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -430,6 +430,7 @@ struct x86_pmu {
pebs_active :1,
pebs_broken :1;
int pebs_record_size;
+ int pebs_buffer_size;
void (*drain_pebs)(struct pt_regs *regs);
struct event_constraint *pebs_constraints;
void (*pebs_aliases)(struct perf_event *event);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index ab3ba1c1b7dd..8ad56b3b0169 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -224,11 +224,11 @@ static int alloc_pebs_buffer(int cpu)
if (!x86_pmu.pebs)
return 0;
- buffer = kzalloc_node(PEBS_BUFFER_SIZE, GFP_KERNEL, node);
+ buffer = kzalloc_node(x86_pmu.pebs_buffer_size, GFP_KERNEL, node);
if (unlikely(!buffer))
return -ENOMEM;
- max = PEBS_BUFFER_SIZE / x86_pmu.pebs_record_size;
+ max = x86_pmu.pebs_buffer_size / x86_pmu.pebs_record_size;
ds->pebs_buffer_base = (u64)(unsigned long)buffer;
ds->pebs_index = ds->pebs_buffer_base;
@@ -1020,6 +1020,7 @@ void intel_ds_init(void)
x86_pmu.bts = boot_cpu_has(X86_FEATURE_BTS);
x86_pmu.pebs = boot_cpu_has(X86_FEATURE_PEBS);
+ x86_pmu.pebs_buffer_size = PEBS_BUFFER_SIZE;
if (x86_pmu.pebs) {
char pebs_type = x86_pmu.intel_cap.pebs_trap ? '+' : '-';
int format = x86_pmu.intel_cap.pebs_format;
@@ -1028,6 +1029,14 @@ void intel_ds_init(void)
case 0:
printk(KERN_CONT "PEBS fmt0%c, ", pebs_type);
x86_pmu.pebs_record_size = sizeof(struct pebs_record_core);
+ /*
+ * Using >PAGE_SIZE buffers makes the WRMSR to
+ * PERF_GLOBAL_CTRL in intel_pmu_enable_all()
+ * mysteriously hang on Core2.
+ *
+ * As a workaround, we don't do this.
+ */
+ x86_pmu.pebs_buffer_size = PAGE_SIZE;
x86_pmu.drain_pebs = intel_pmu_drain_pebs_core;
break;
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a0ad220c96692eda76b2e3fd7279f3dcd1d8a8ff upstream.
A malicious device missing interface can make the driver oops.
Add sanity checking.
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/misc/ims-pcu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index e204f26b0011..77164dc1bedd 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1433,6 +1433,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev,
union_desc->bMasterInterface0);
+ if (!pcu->ctrl_intf)
+ return -EINVAL;
alt = pcu->ctrl_intf->cur_altsetting;
pcu->ep_ctrl = &alt->endpoint[0].desc;
@@ -1440,6 +1442,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
pcu->data_intf = usb_ifnum_to_if(pcu->udev,
union_desc->bSlaveInterface0);
+ if (!pcu->data_intf)
+ return -EINVAL;
alt = pcu->data_intf->cur_altsetting;
if (alt->desc.bNumEndpoints != 2) {
--
2.8.1
From: "Steven Rostedt (Red Hat)" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3debb0a9ddb16526de8b456491b7db60114f7b5e upstream.
The trace_printk() code will allocate extra buffers if the compile detects
that a trace_printk() is used. To do this, the format of the trace_printk()
is saved to the __trace_printk_fmt section, and if that section is bigger
than zero, the buffers are allocated (along with a message that this has
happened).
If trace_printk() uses a format that is not a constant, and thus something
not guaranteed to be around when the print happens, the compiler optimizes
the fmt out, as it is not used, and the __trace_printk_fmt section is not
filled. This means the kernel will not allocate the special buffers needed
for the trace_printk() and the trace_printk() will not write anything to the
tracing buffer.
Adding a "__used" to the variable in the __trace_printk_fmt section will
keep it around, even though it is set to NULL. This will keep the string
from being printed in the debugfs/tracing/printk_formats section as it is
not needed.
Reported-by: Vlastimil Babka <[email protected]>
Fixes: 07d777fe8c398 "tracing: Add percpu buffers for trace_printk()"
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/kernel.h | 6 +++---
kernel/trace/trace_printk.c | 3 +++
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 93bfc3a7e0a3..11fdfda99b3c 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -567,7 +567,7 @@ do { \
#define do_trace_printk(fmt, args...) \
do { \
- static const char *trace_printk_fmt \
+ static const char *trace_printk_fmt __used \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
@@ -611,7 +611,7 @@ int __trace_printk(unsigned long ip, const char *fmt, ...);
*/
#define trace_puts(str) ({ \
- static const char *trace_printk_fmt \
+ static const char *trace_printk_fmt __used \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(str) ? str : NULL; \
\
@@ -633,7 +633,7 @@ extern void trace_dump_stack(int skip);
#define ftrace_vprintk(fmt, vargs) \
do { \
if (__builtin_constant_p(fmt)) { \
- static const char *trace_printk_fmt \
+ static const char *trace_printk_fmt __used \
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 7c8cef653166..7b900474209d 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -292,6 +292,9 @@ static int t_show(struct seq_file *m, void *v)
const char *str = *fmt;
int i;
+ if (!*fmt)
+ return 0;
+
seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
/*
--
2.8.1
From: Vladis Dronov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 950336ba3e4a1ffd2ca60d29f6ef386dd2c7351d upstream.
The ati_remote2 driver expects at least two interfaces with one
endpoint each. If given malicious descriptor that specify one
interface or no endpoints, it will crash in the probe function.
Ensure there is at least two interfaces and one endpoint for each
interface before using it.
The full disclosure: http://seclists.org/bugtraq/2016/Mar/90
Reported-by: Ralf Spenneberg <[email protected]>
Signed-off-by: Vladis Dronov <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/misc/ati_remote2.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index f63341f20b91..e8c6a4842e91 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
ar2->udev = udev;
+ /* Sanity check, first interface must have an endpoint */
+ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
+ dev_err(&interface->dev,
+ "%s(): interface 0 must have an endpoint\n", __func__);
+ r = -ENODEV;
+ goto fail1;
+ }
ar2->intf[0] = interface;
ar2->ep[0] = &alt->endpoint[0].desc;
+ /* Sanity check, the device must have two interfaces */
ar2->intf[1] = usb_ifnum_to_if(udev, 1);
+ if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) {
+ dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n",
+ __func__, udev->actconfig->desc.bNumInterfaces);
+ r = -ENODEV;
+ goto fail1;
+ }
+
r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
if (r)
goto fail1;
+
+ /* Sanity check, second interface must have an endpoint */
alt = ar2->intf[1]->cur_altsetting;
+ if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) {
+ dev_err(&interface->dev,
+ "%s(): interface 1 must have an endpoint\n", __func__);
+ r = -ENODEV;
+ goto fail2;
+ }
ar2->ep[1] = &alt->endpoint[0].desc;
r = ati_remote2_urb_init(ar2);
if (r)
- goto fail2;
+ goto fail3;
ar2->channel_mask = channel_mask;
ar2->mode_mask = mode_mask;
r = ati_remote2_setup(ar2, ar2->channel_mask);
if (r)
- goto fail2;
+ goto fail3;
usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
@@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group);
if (r)
- goto fail2;
+ goto fail3;
r = ati_remote2_input_init(ar2);
if (r)
- goto fail3;
+ goto fail4;
usb_set_intfdata(interface, ar2);
@@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
return 0;
- fail3:
+ fail4:
sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group);
- fail2:
+ fail3:
ati_remote2_urb_cleanup(ar2);
+ fail2:
usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
fail1:
kfree(ar2);
--
2.8.1
From: Thomas Gleixner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e9532e69b8d1d1284e8ecf8d2586de34aec61244 upstream.
On CPU hotplug the steal time accounting can keep a stale rq->prev_steal_time
value over CPU down and up. So after the CPU comes up again the delta
calculation in steal_account_process_tick() wreckages itself due to the
unsigned math:
u64 steal = paravirt_steal_clock(smp_processor_id());
steal -= this_rq()->prev_steal_time;
So if steal is smaller than rq->prev_steal_time we end up with an insane large
value which then gets added to rq->prev_steal_time, resulting in a permanent
wreckage of the accounting. As a consequence the per CPU stats in /proc/stat
become stale.
Nice trick to tell the world how idle the system is (100%) while the CPU is
100% busy running tasks. Though we prefer realistic numbers.
None of the accounting values which use a previous value to account for
fractions is reset at CPU hotplug time. update_rq_clock_task() has a sanity
check for prev_irq_time and prev_steal_time_rq, but that sanity check solely
deals with clock warps and limits the /proc/stat visible wreckage. The
prev_time values are still wrong.
Solution is simple: Reset rq->prev_*_time when the CPU is plugged in again.
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Rik van Riel <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Glauber Costa <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Fixes: commit 095c0aa83e52 "sched: adjust scheduler cpu power for stolen time"
Fixes: commit aa483808516c "sched: Remove irq time from available CPU power"
Fixes: commit e6e6685accfa "KVM guest: Steal time accounting"
Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1603041539490.3686@nanos
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/sched/core.c | 1 +
kernel/sched/sched.h | 13 +++++++++++++
2 files changed, 14 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 7381119ec1e9..dd794a9b6850 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4710,6 +4710,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
case CPU_UP_PREPARE:
rq->calc_load_update = calc_load_update;
+ account_reset_rq(rq);
break;
case CPU_ONLINE:
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index e09e3e0466f7..2f761b74dee3 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1383,3 +1383,16 @@ static inline u64 irq_time_read(int cpu)
}
#endif /* CONFIG_64BIT */
#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
+
+static inline void account_reset_rq(struct rq *rq)
+{
+#ifdef CONFIG_IRQ_TIME_ACCOUNTING
+ rq->prev_irq_time = 0;
+#endif
+#ifdef CONFIG_PARAVIRT
+ rq->prev_steal_time = 0;
+#endif
+#ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING
+ rq->prev_steal_time_rq = 0;
+#endif
+}
--
2.8.1
From: Joseph Qi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit be12b299a83fc807bbaccd2bcb8ec50cbb0cb55c upstream.
When master handles convert request, it queues ast first and then
returns status. This may happen that the ast is sent before the request
status because the above two messages are sent by two threads. And
right after the ast is sent, if master down, it may trigger BUG in
dlm_move_lockres_to_recovery_list in the requested node because ast
handler moves it to grant list without clear lock->convert_pending. So
remove BUG_ON statement and check if the ast is processed in
dlmconvert_remote.
Signed-off-by: Joseph Qi <[email protected]>
Reported-by: Yiwen Jiang <[email protected]>
Cc: Junxiao Bi <[email protected]>
Cc: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Cc: Tariq Saeed <[email protected]>
Cc: Junxiao Bi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ocfs2/dlm/dlmconvert.c | 13 +++++++++++++
fs/ocfs2/dlm/dlmrecovery.c | 1 -
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
index 84de55ed865a..f90931335c6b 100644
--- a/fs/ocfs2/dlm/dlmconvert.c
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -288,6 +288,19 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm,
status = DLM_DENIED;
goto bail;
}
+
+ if (lock->ml.type == type && lock->ml.convert_type == LKM_IVMODE) {
+ mlog(0, "last convert request returned DLM_RECOVERING, but "
+ "owner has already queued and sent ast to me. res %.*s, "
+ "(cookie=%u:%llu, type=%d, conv=%d)\n",
+ res->lockname.len, res->lockname.name,
+ dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)),
+ dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)),
+ lock->ml.type, lock->ml.convert_type);
+ status = DLM_NORMAL;
+ goto bail;
+ }
+
res->state |= DLM_LOCK_RES_IN_PROGRESS;
/* move lock to local convert queue */
/* do not alter lock refcount. switching lists. */
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index 12b035548e45..b975dffc1c6d 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -2033,7 +2033,6 @@ void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
dlm_lock_get(lock);
if (lock->convert_pending) {
/* move converting lock back to granted */
- BUG_ON(i != DLM_CONVERTING_LIST);
mlog(0, "node died with convert pending "
"on %.*s. move back to granted list.\n",
res->lockname.len, res->lockname.name);
--
2.8.1
From: Aaro Koskinen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5e64c29e98bfbba1b527b0a164f9493f3db9e8cb upstream.
Commit 5942ddbc500d ("mtd: introduce mtd_block_markbad interface")
incorrectly changed onenand_block_markbad() to call mtd_block_markbad
instead of onenand_chip's block_markbad function. As a result the function
will now recurse and deadlock. Fix by reverting the change.
Fixes: 5942ddbc500d ("mtd: introduce mtd_block_markbad interface")
Signed-off-by: Aaro Koskinen <[email protected]>
Acked-by: Artem Bityutskiy <[email protected]>
Signed-off-by: Brian Norris <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mtd/onenand/onenand_base.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index b3f41f200622..0f13fd4748ec 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -2610,6 +2610,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
*/
static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
+ struct onenand_chip *this = mtd->priv;
int ret;
ret = onenand_block_isbad(mtd, ofs);
@@ -2621,7 +2622,7 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
onenand_get_device(mtd, FL_WRITING);
- ret = mtd_block_markbad(mtd, ofs);
+ ret = this->block_markbad(mtd, ofs);
onenand_release_device(mtd);
return ret;
}
--
2.8.1
From: Joseph Qi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ac7cf246dfdbec3d8fed296c7bf30e16f5099dac upstream.
There is a race window between dlmconvert_remote and
dlm_move_lockres_to_recovery_list, which will cause a lock with
OCFS2_LOCK_BUSY in grant list, thus system hangs.
dlmconvert_remote
{
spin_lock(&res->spinlock);
list_move_tail(&lock->list, &res->converting);
lock->convert_pending = 1;
spin_unlock(&res->spinlock);
status = dlm_send_remote_convert_request();
>>>>>> race window, master has queued ast and return DLM_NORMAL,
and then down before sending ast.
this node detects master down and calls
dlm_move_lockres_to_recovery_list, which will revert the
lock to grant list.
Then OCFS2_LOCK_BUSY won't be cleared as new master won't
send ast any more because it thinks already be authorized.
spin_lock(&res->spinlock);
lock->convert_pending = 0;
if (status != DLM_NORMAL)
dlm_revert_pending_convert(res, lock);
spin_unlock(&res->spinlock);
}
In this case, check if res->state has DLM_LOCK_RES_RECOVERING bit set
(res is still in recovering) or res master changed (new master has
finished recovery), reset the status to DLM_RECOVERING, then it will
retry convert.
Signed-off-by: Joseph Qi <[email protected]>
Reported-by: Yiwen Jiang <[email protected]>
Reviewed-by: Junxiao Bi <[email protected]>
Cc: Mark Fasheh <[email protected]>
Cc: Joel Becker <[email protected]>
Cc: Tariq Saeed <[email protected]>
Cc: Junxiao Bi <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ocfs2/dlm/dlmconvert.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
index e36d63ff1783..84de55ed865a 100644
--- a/fs/ocfs2/dlm/dlmconvert.c
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -262,6 +262,7 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm,
struct dlm_lock *lock, int flags, int type)
{
enum dlm_status status;
+ u8 old_owner = res->owner;
mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type,
lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS);
@@ -316,11 +317,19 @@ enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm,
spin_lock(&res->spinlock);
res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
lock->convert_pending = 0;
- /* if it failed, move it back to granted queue */
+ /* if it failed, move it back to granted queue.
+ * if master returns DLM_NORMAL and then down before sending ast,
+ * it may have already been moved to granted queue, reset to
+ * DLM_RECOVERING and retry convert */
if (status != DLM_NORMAL) {
if (status != DLM_NOTQUEUED)
dlm_error(status);
dlm_revert_pending_convert(res, lock);
+ } else if ((res->state & DLM_LOCK_RES_RECOVERING) ||
+ (old_owner != res->owner)) {
+ mlog(0, "res %.*s is in recovering or has been recovered.\n",
+ res->lockname.len, res->lockname.name);
+ status = DLM_RECOVERING;
}
bail:
spin_unlock(&res->spinlock);
--
2.8.1
From: Jes Sorensen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e7597e69dec59b65c5525db1626b9d34afdfa678 upstream.
'max_discard_sectors' is in sectors, while 'stripe' is in bytes.
This fixes the problem where DISCARD would get disabled on some larger
RAID5 configurations (6 or more drives in my testing), while it worked
as expected with smaller configurations.
Fixes: 620125f2bf8 ("MD: raid5 trim support")
Signed-off-by: Jes Sorensen <[email protected]>
Signed-off-by: Shaohua Li <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/raid5.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 4881851c4b42..9fbc77c6e132 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5985,8 +5985,8 @@ static int run(struct mddev *mddev)
}
if (discard_supported &&
- mddev->queue->limits.max_discard_sectors >= stripe &&
- mddev->queue->limits.discard_granularity >= stripe)
+ mddev->queue->limits.max_discard_sectors >= (stripe >> 9) &&
+ mddev->queue->limits.discard_granularity >= stripe)
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
mddev->queue);
else
--
2.8.1
From: Himanshu Madhani <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5e47f1985d7107331c3f64fb3ec83d66fd73577e upstream.
This patch fixes an active I/O shutdown bug for fabric
drivers using target_wait_for_sess_cmds(), where se_cmd
descriptor shutdown would result in hung tasks waiting
indefinitely for se_cmd->cmd_wait_comp to complete().
To address this bug, drop the incorrect list_del_init()
usage in target_wait_for_sess_cmds() and always complete()
during se_cmd target_release_cmd_kref() put, in order to
let caller invoke the final fabric release callback
into se_cmd->se_tfo->release_cmd() code.
[3.12 backport: we have only list_del]
Reported-by: Himanshu Madhani <[email protected]>
Tested-by: Himanshu Madhani <[email protected]>
Signed-off-by: Himanshu Madhani <[email protected]>
Signed-off-by: Nicholas Bellinger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/target/target_core_transport.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index b335709f050f..9291eaa09046 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2438,8 +2438,6 @@ void target_wait_for_sess_cmds(struct se_session *se_sess)
list_for_each_entry_safe(se_cmd, tmp_cmd,
&se_sess->sess_wait_list, se_cmd_list) {
- list_del(&se_cmd->se_cmd_list);
-
pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
" %d\n", se_cmd, se_cmd->t_state,
se_cmd->se_tfo->get_cmd_state(se_cmd));
--
2.8.1
From: Max Filippov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 362014c8d9d51d504c167c44ac280169457732be upstream.
Simulator stdin may be connected to a file, when its end is reached
kernel hangs in infinite loop inside rs_poll, because simc_poll always
signals that descriptor 0 is readable and simc_read always returns 0.
Check simc_read return value and exit loop if it's not positive. Also
don't rewind polling timer if it's zero.
Signed-off-by: Max Filippov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/xtensa/platforms/iss/console.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 70cb408bc20d..92d785fefb6d 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -100,21 +100,23 @@ static void rs_poll(unsigned long priv)
{
struct tty_port *port = (struct tty_port *)priv;
int i = 0;
+ int rd = 1;
unsigned char c;
spin_lock(&timer_lock);
while (simc_poll(0)) {
- simc_read(0, &c, 1);
+ rd = simc_read(0, &c, 1);
+ if (rd <= 0)
+ break;
tty_insert_flip_char(port, c, TTY_NORMAL);
i++;
}
if (i)
tty_flip_buffer_push(port);
-
-
- mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+ if (rd)
+ mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
spin_unlock(&timer_lock);
}
--
2.8.1
From: Jiri Kosina <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c8b08ca558c0067bc9e15ce3f1e70af260410bb2 upstream.
mkspec is copying built kernel to temporrary location
/boot/vmlinuz-$KERNELRELEASE-rpm
and runs installkernel on it. This however directly leads to grub2
menuentry for this suffixed binary being generated as well during the run
of installkernel script.
Later in the process the temporary -rpm suffixed files are removed, and
therefore we end up with spurious (and non-functional) grub2 menu entries
for each installed kernel RPM.
Fix that by using a different temporary name (prefixed by '.'), so that
the binary is not recognized as an actual kernel binary and no menuentry
is created for it.
Signed-off-by: Jiri Kosina <[email protected]>
Fixes: 3c9c7a14b627 ("rpm-pkg: add %post section to create initramfs and grub hooks")
Signed-off-by: Michal Marek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
scripts/package/mkspec | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 13957602f7ca..c92358d61e26 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -131,11 +131,11 @@ echo 'rm -rf $RPM_BUILD_ROOT'
echo ""
echo "%post"
echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then"
-echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/vmlinuz-$KERNELRELEASE-rpm"
-echo "cp /boot/System.map-$KERNELRELEASE /boot/System.map-$KERNELRELEASE-rpm"
+echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm"
+echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm"
echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE"
-echo "/sbin/installkernel $KERNELRELEASE /boot/vmlinuz-$KERNELRELEASE-rpm /boot/System.map-$KERNELRELEASE-rpm"
-echo "rm -f /boot/vmlinuz-$KERNELRELEASE-rpm /boot/System.map-$KERNELRELEASE-rpm"
+echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
+echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
echo "fi"
echo ""
echo "%files"
--
2.8.1
From: "Michael S. Tsirkin" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 10e7ac22cdd4d211cef99afcb9371b70cb175be6 upstream.
Calling return copy_to_user(...) in an ioctl will not do the right thing
if there's a pagefault: copy_to_user returns the number of bytes not
copied in this case.
Fix up watchdog/rc32434_wdt to do
return copy_to_user(...)) ? -EFAULT : 0;
instead.
Signed-off-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Wim Van Sebroeck <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/watchdog/rc32434_wdt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c
index 9cf6bc7a234f..6f1ffd94a202 100644
--- a/drivers/watchdog/rc32434_wdt.c
+++ b/drivers/watchdog/rc32434_wdt.c
@@ -238,7 +238,7 @@ static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
/* Fall through */
case WDIOC_GETTIMEOUT:
- return copy_to_user(argp, &timeout, sizeof(int));
+ return copy_to_user(argp, &timeout, sizeof(int)) ? -EFAULT : 0;
default:
return -ENOTTY;
}
--
2.8.1
From: "Vittorio Gambaletta (VittGam)" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4061db03dd71d195b9973ee466f6ed32f6a3fc16 upstream.
The clock measurement on the AC'97 audio card found in the IBM ThinkPad X41
will often fail, so add a quirk entry to fix it.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=441087
Signed-off-by: Vittorio Gambaletta <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/pci/intel8x0.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 59c8aaebb91e..c55292ef8d99 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2885,6 +2885,7 @@ static void intel8x0_measure_ac97_clock(struct intel8x0 *chip)
static struct snd_pci_quirk intel8x0_clock_list[] = {
SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
+ SND_PCI_QUIRK(0x1014, 0x0581, "AD1981B", 48000),
SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
--
2.8.1
From: Julia Lawall <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1b669e713f277a4d4b3cec84e13d16544ac8286d upstream.
& is no longer allowed in column 0, since Coccinelle 1.0.4.
Signed-off-by: Julia Lawall <[email protected]>
Tested-by: Nishanth Menon <[email protected]>
Signed-off-by: Michal Marek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
scripts/coccinelle/iterators/use_after_iter.cocci | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/coccinelle/iterators/use_after_iter.cocci b/scripts/coccinelle/iterators/use_after_iter.cocci
index f085f5968c52..ce8cc9c006e5 100644
--- a/scripts/coccinelle/iterators/use_after_iter.cocci
+++ b/scripts/coccinelle/iterators/use_after_iter.cocci
@@ -123,7 +123,7 @@ list_remove_head(x,c,...)
|
sizeof(<+...c...+>)
|
-&c->member
+ &c->member
|
c = E
|
--
2.8.1
From: "Steven Rostedt (Red Hat)" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a29054d9478d0435ab01b7544da4f674ab13f533 upstream.
If tracing contains data and the trace_pipe file is read with sendfile(),
then it can trigger a NULL pointer dereference and various BUG_ON within the
VM code.
There's a patch to fix this in the splice_to_pipe() code, but it's also a
good idea to not let that happen from trace_pipe either.
Link: http://lkml.kernel.org/r/[email protected]
Reported-by: Rabin Vincent <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/trace/trace.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1b51436db225..12cff54899ee 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4362,7 +4362,10 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
spd.nr_pages = i;
- ret = splice_to_pipe(pipe, &spd);
+ if (i)
+ ret = splice_to_pipe(pipe, &spd);
+ else
+ ret = 0;
out:
splice_shrink_spd(&spd);
return ret;
--
2.8.1
From: "Steven Rostedt (Red Hat)" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cb86e05390debcc084cfdb0a71ed4c5dbbec517d upstream.
Joel Fernandes reported that the function tracing of preempt disabled
sections was not being reported when running either the preemptirqsoff or
preemptoff tracers. This was due to the fact that the function tracer
callback for those tracers checked if irqs were disabled before tracing. But
this fails when we want to trace preempt off locations as well.
Joel explained that he wanted to see funcitons where interrupts are enabled
but preemption was disabled. The expected output he wanted:
<...>-2265 1d.h1 3419us : preempt_count_sub <-irq_exit
<...>-2265 1d..1 3419us : __do_softirq <-irq_exit
<...>-2265 1d..1 3419us : msecs_to_jiffies <-__do_softirq
<...>-2265 1d..1 3420us : irqtime_account_irq <-__do_softirq
<...>-2265 1d..1 3420us : __local_bh_disable_ip <-__do_softirq
<...>-2265 1..s1 3421us : run_timer_softirq <-__do_softirq
<...>-2265 1..s1 3421us : hrtimer_run_pending <-run_timer_softirq
<...>-2265 1..s1 3421us : _raw_spin_lock_irq <-run_timer_softirq
<...>-2265 1d.s1 3422us : preempt_count_add <-_raw_spin_lock_irq
<...>-2265 1d.s2 3422us : _raw_spin_unlock_irq <-run_timer_softirq
<...>-2265 1..s2 3422us : preempt_count_sub <-_raw_spin_unlock_irq
<...>-2265 1..s1 3423us : rcu_bh_qs <-__do_softirq
<...>-2265 1d.s1 3423us : irqtime_account_irq <-__do_softirq
<...>-2265 1d.s1 3423us : __local_bh_enable <-__do_softirq
There's a comment saying that the irq disabled check is because there's a
possible race that tracing_cpu may be set when the function is executed. But
I don't remember that race. For now, I added a check for preemption being
enabled too to not record the function, as there would be no race if that
was the case. I need to re-investigate this, as I'm now thinking that the
tracing_cpu will always be correct. But no harm in keeping the check for
now, except for the slight performance hit.
Link: http://lkml.kernel.org/r/[email protected]
Fixes: 5e6d2b9cfa3a "tracing: Use one prologue for the preempt irqs off tracer function tracers"
Reported-by: Joel Fernandes <[email protected]>
Signed-off-by: Steven Rostedt <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/trace/trace_irqsoff.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 2aefbee93a6d..56e083e26ca9 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -118,8 +118,12 @@ static int func_prolog_dec(struct trace_array *tr,
return 0;
local_save_flags(*flags);
- /* slight chance to get a false positive on tracing_cpu */
- if (!irqs_disabled_flags(*flags))
+ /*
+ * Slight chance to get a false positive on tracing_cpu,
+ * although I'm starting to think there isn't a chance.
+ * Leave this for now just to be paranoid.
+ */
+ if (!irqs_disabled_flags(*flags) && !preempt_count())
return 0;
*data = per_cpu_ptr(tr->trace_buffer.data, cpu);
--
2.8.1
From: Aurelien Jacquiot <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 36915976eca58f2eefa040ba8f9939672564df61 upstream.
Fix deadlocking during concurrent receive and transmit operations on SMP
platforms caused by the use of incorrect lock: on transmit 'tx_lock'
spinlock should be used instead of 'lock' which is used for receive
operation.
This fix is applicable to kernel versions starting from v2.15.
Signed-off-by: Aurelien Jacquiot <[email protected]>
Signed-off-by: Alexandre Bounine <[email protected]>
Cc: Matt Porter <[email protected]>
Cc: Andre van Herk <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/rionet.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 6d1f6ed3113f..d93bac129efc 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -280,7 +280,7 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo
struct net_device *ndev = dev_id;
struct rionet_private *rnet = netdev_priv(ndev);
- spin_lock(&rnet->lock);
+ spin_lock(&rnet->tx_lock);
if (netif_msg_intr(rnet))
printk(KERN_INFO
@@ -299,7 +299,7 @@ static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbo
if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
netif_wake_queue(ndev);
- spin_unlock(&rnet->lock);
+ spin_unlock(&rnet->tx_lock);
}
static int rionet_open(struct net_device *ndev)
--
2.8.1
From: Mario Kleiner <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 459ee1c3fd097ab56ababd8ff4bb7ef6a792de33 upstream.
As observed on Apple iMac10,1, DCE-3.2, RV-730,
link rate of 2.7 Ghz is not selected, because
the args.v1.ucConfig flag setting for 2.7 Ghz
gets overwritten by a following assignment of
the transmitter to use.
Move link rate setup a few lines down to fix this.
In practice this didn't have any positive or
negative effect on display setup on the tested
iMac10,1 so i don't know if backporting to stable
makes sense or not.
Signed-off-by: Mario Kleiner <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/atombios_encoders.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
index 6a965172d8dd..a05c4c0e3799 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -894,8 +894,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
else
args.v1.ucLaneNum = 4;
- if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
- args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
@@ -912,6 +910,10 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
else
args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+
+ if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode) && (dp_clock == 270000))
+ args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
+
break;
case 2:
case 3:
--
2.8.1
From: Hans Verkuil <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b339a72e04a62f0b1882c43492fc712f1176b3e6 upstream.
The V4L2_CID_TX_EDID_PRESENT control reports if an EDID is present.
The adv7511 however still reported the EDID present after disconnecting
the HDMI cable. Fix the logic regarding this control. And when the EDID
is disconnected also call ADV7511_EDID_DETECT to notify the bridge driver.
This was also missing.
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/i2c/adv7511.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index 7c8d971f1f61..71995401eab0 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -804,12 +804,23 @@ static void adv7511_dbg_dump_edid(int lvl, int debug, struct v4l2_subdev *sd, in
}
}
+static void adv7511_notify_no_edid(struct v4l2_subdev *sd)
+{
+ struct adv7511_state *state = get_adv7511_state(sd);
+ struct adv7511_edid_detect ed;
+
+ /* We failed to read the EDID, so send an event for this. */
+ ed.present = false;
+ ed.segment = adv7511_rd(sd, 0xc4);
+ v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+ v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x0);
+}
+
static void adv7511_edid_handler(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct adv7511_state *state = container_of(dwork, struct adv7511_state, edid_handler);
struct v4l2_subdev *sd = &state->sd;
- struct adv7511_edid_detect ed;
v4l2_dbg(1, debug, sd, "%s:\n", __func__);
@@ -834,9 +845,7 @@ static void adv7511_edid_handler(struct work_struct *work)
}
/* We failed to read the EDID, so send an event for this. */
- ed.present = false;
- ed.segment = adv7511_rd(sd, 0xc4);
- v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
+ adv7511_notify_no_edid(sd);
v4l2_dbg(1, debug, sd, "%s: no edid found\n", __func__);
}
@@ -907,7 +916,6 @@ static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd)
/* update read only ctrls */
v4l2_ctrl_s_ctrl(state->hotplug_ctrl, adv7511_have_hotplug(sd) ? 0x1 : 0x0);
v4l2_ctrl_s_ctrl(state->rx_sense_ctrl, adv7511_have_rx_sense(sd) ? 0x1 : 0x0);
- v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
if ((status & MASK_ADV7511_HPD_DETECT) && ((status & MASK_ADV7511_MSEN_DETECT) || state->edid.segments)) {
v4l2_dbg(1, debug, sd, "%s: hotplug and (rx-sense or edid)\n", __func__);
@@ -937,6 +945,7 @@ static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd)
}
adv7511_s_power(sd, false);
memset(&state->edid, 0, sizeof(struct adv7511_state_edid));
+ adv7511_notify_no_edid(sd);
}
}
@@ -1000,6 +1009,7 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
}
/* one more segment read ok */
state->edid.segments = segment + 1;
+ v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, 0x1);
if (((state->edid.data[0x7e] >> 1) + 1) > state->edid.segments) {
/* Request next EDID segment */
v4l2_dbg(1, debug, sd, "%s: request segment %d\n", __func__, state->edid.segments);
@@ -1019,7 +1029,6 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
ed.present = true;
ed.segment = 0;
state->edid_detect_counter++;
- v4l2_ctrl_s_ctrl(state->have_edid0_ctrl, state->edid.segments ? 0x1 : 0x0);
v4l2_subdev_notify(sd, ADV7511_EDID_DETECT, (void *)&ed);
return ed.present;
}
--
2.8.1
From: Mateusz Guzik <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2e83b79b2d6c78bf1b4aa227938a214dcbddc83f upstream.
This plugs 2 trivial leaks in xfs_attr_shortform_list and
xfs_attr3_leaf_list_int.
Signed-off-by: Mateusz Guzik <[email protected]>
Reviewed-by: Eric Sandeen <[email protected]>
Signed-off-by: Dave Chinner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/xfs/xfs_attr_list.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index cbc80d485177..fdc9d98303e4 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -207,8 +207,10 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
sbp->namelen,
sbp->valuelen,
&sbp->name[sbp->namelen]);
- if (error)
+ if (error) {
+ kmem_free(sbuf);
return error;
+ }
if (context->seen_enough)
break;
cursor->offset++;
@@ -454,14 +456,13 @@ xfs_attr3_leaf_list_int(
args.rmtblkcnt = xfs_attr3_rmt_blocks(
args.dp->i_mount, valuelen);
retval = xfs_attr_rmtval_get(&args);
- if (retval)
- return retval;
- retval = context->put_listent(context,
- entry->flags,
- name_rmt->name,
- (int)name_rmt->namelen,
- valuelen,
- args.value);
+ if (!retval)
+ retval = context->put_listent(context,
+ entry->flags,
+ name_rmt->name,
+ (int)name_rmt->namelen,
+ valuelen,
+ args.value);
kmem_free(args.value);
} else {
retval = context->put_listent(context,
--
2.8.1
From: Rabin Vincent <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d6785d9152147596f60234157da2b02540c3e60f upstream.
Running the following command:
busybox cat /sys/kernel/debug/tracing/trace_pipe > /dev/null
with any tracing enabled pretty very quickly leads to various NULL
pointer dereferences and VM BUG_ON()s, such as these:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000020
IP: [<ffffffff8119df6c>] generic_pipe_buf_release+0xc/0x40
Call Trace:
[<ffffffff811c48a3>] splice_direct_to_actor+0x143/0x1e0
[<ffffffff811c42e0>] ? generic_pipe_buf_nosteal+0x10/0x10
[<ffffffff811c49cf>] do_splice_direct+0x8f/0xb0
[<ffffffff81196869>] do_sendfile+0x199/0x380
[<ffffffff81197600>] SyS_sendfile64+0x90/0xa0
[<ffffffff8192cbee>] entry_SYSCALL_64_fastpath+0x12/0x6d
page dumped because: VM_BUG_ON_PAGE(atomic_read(&page->_count) == 0)
kernel BUG at include/linux/mm.h:367!
invalid opcode: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
RIP: [<ffffffff8119df9c>] generic_pipe_buf_release+0x3c/0x40
Call Trace:
[<ffffffff811c48a3>] splice_direct_to_actor+0x143/0x1e0
[<ffffffff811c42e0>] ? generic_pipe_buf_nosteal+0x10/0x10
[<ffffffff811c49cf>] do_splice_direct+0x8f/0xb0
[<ffffffff81196869>] do_sendfile+0x199/0x380
[<ffffffff81197600>] SyS_sendfile64+0x90/0xa0
[<ffffffff8192cd1e>] tracesys_phase2+0x84/0x89
(busybox's cat uses sendfile(2), unlike the coreutils version)
This is because tracing_splice_read_pipe() can call splice_to_pipe()
with spd->nr_pages == 0. spd_pages underflows in splice_to_pipe() and
we fill the page pointers and the other fields of the pipe_buffers with
garbage.
All other callers of splice_to_pipe() avoid calling it when nr_pages ==
0, and we could make tracing_splice_read_pipe() do that too, but it
seems reasonable to have splice_to_page() handle this condition
gracefully.
Signed-off-by: Rabin Vincent <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/splice.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/splice.c b/fs/splice.c
index 76cbc01df6a4..51ce51b9af6a 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -189,6 +189,9 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
unsigned int spd_pages = spd->nr_pages;
int ret, do_wakeup, page_nr;
+ if (!spd_pages)
+ return 0;
+
ret = 0;
do_wakeup = 0;
page_nr = 0;
--
2.8.1
From: Max Filippov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7de7ac785ae18a2cdc78d7560f48e3213d9ea0ab upstream.
There are XCHAL_NUM_DBREAK registers, clear them all.
This also fixes cryptic assembler error message with binutils 2.25 when
XCHAL_NUM_DBREAK is 0:
as: out of memory allocating 18446744073709551575 bytes after a total
of 495616 bytes
Signed-off-by: Max Filippov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/xtensa/kernel/head.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 7d740ebbe198..bb12d778f64f 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -118,7 +118,7 @@ ENTRY(_startup)
wsr a0, icountlevel
.set _index, 0
- .rept XCHAL_NUM_DBREAK - 1
+ .rept XCHAL_NUM_DBREAK
wsr a0, SREG_DBREAKC + _index
.set _index, _index + 1
.endr
--
2.8.1
On 04/11/2016 06:23 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.58 release.
> There are 98 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 Wed Apr 13 15:21:57 CEST 2016.
> Anything received after that time might be too late.
>
Build results:
total: 125 pass: 125 fail: 0
Qemu test results:
total: 84 pass: 84 fail: 0
Details are available at http://kerneltests.org/builders.
Guenter
From: Peter Hurley <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 401879c57f01cbf2da204ad2e8db910525c6dbea upstream.
The N_IRDA line discipline may access the previous line discipline's closed
and already-fre private data on open [1].
The tty->disc_data field _never_ refers to valid data on entry to the
line discipline's open() method. Rather, the ldisc is expected to
initialize that field for its own use for the lifetime of the instance
(ie. from open() to close() only).
[1]
==================================================================
BUG: KASAN: use-after-free in irtty_open+0x422/0x550 at addr ffff8800331dd068
Read of size 4 by task a.out/13960
=============================================================================
BUG kmalloc-512 (Tainted: G B ): kasan: bad access detected
-----------------------------------------------------------------------------
...
Call Trace:
[<ffffffff815fa2ae>] __asan_report_load4_noabort+0x3e/0x40 mm/kasan/report.c:279
[<ffffffff836938a2>] irtty_open+0x422/0x550 drivers/net/irda/irtty-sir.c:436
[<ffffffff829f1b80>] tty_ldisc_open.isra.2+0x60/0xa0 drivers/tty/tty_ldisc.c:447
[<ffffffff829f21c0>] tty_set_ldisc+0x1a0/0x940 drivers/tty/tty_ldisc.c:567
[< inline >] tiocsetd drivers/tty/tty_io.c:2650
[<ffffffff829da49e>] tty_ioctl+0xace/0x1fd0 drivers/tty/tty_io.c:2883
[< inline >] vfs_ioctl fs/ioctl.c:43
[<ffffffff816708ac>] do_vfs_ioctl+0x57c/0xe60 fs/ioctl.c:607
[< inline >] SYSC_ioctl fs/ioctl.c:622
[<ffffffff81671204>] SyS_ioctl+0x74/0x80 fs/ioctl.c:613
[<ffffffff852a7876>] entry_SYSCALL_64_fastpath+0x16/0x7a
Reported-and-tested-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Peter Hurley <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/irda/irtty-sir.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 177441afeb96..aef74c69a661 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -430,16 +430,6 @@ static int irtty_open(struct tty_struct *tty)
/* Module stuff handled via irda_ldisc.owner - Jean II */
- /* First make sure we're not already connected. */
- if (tty->disc_data != NULL) {
- priv = tty->disc_data;
- if (priv && priv->magic == IRTTY_MAGIC) {
- ret = -EEXIST;
- goto out;
- }
- tty->disc_data = NULL; /* ### */
- }
-
/* stop the underlying driver */
irtty_stop_receiver(tty, TRUE);
if (tty->ops->stop)
--
2.8.1
From: Dmitry Tunin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 28c971d82fb58ef7cba22e5308be6d2d2590473d upstream.
T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=02 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=0489 ProdID=e095 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
This device requires ar3k/AthrBT_0x31010100.dfu and
ar3k/ramps_0x31010100_40.dfu firmware files that are not in
linux-firmware yet.
BugLink: https://bugs.launchpad.net/bugs/1542944
Signed-off-by: Dmitry Tunin <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 2a3e5ffbbf40..78e7f1a003be 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -82,6 +82,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0489, 0xe05f) },
{ USB_DEVICE(0x0489, 0xe076) },
{ USB_DEVICE(0x0489, 0xe078) },
+ { USB_DEVICE(0x0489, 0xe095) },
{ USB_DEVICE(0x04c5, 0x1330) },
{ USB_DEVICE(0x04CA, 0x3004) },
{ USB_DEVICE(0x04CA, 0x3005) },
@@ -147,6 +148,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 7c9ca5995424..a38d7d21f8a1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -159,6 +159,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
--
2.8.1
From: Eric Wheeler <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f8b11260a445169989d01df75d35af0f56178f95 upstream.
When bch_cache_set_alloc() fails to kzalloc the cache_set, the
asyncronous closure handling tries to dereference a cache_set that
hadn't yet been allocated inside of cache_set_flush() which is called
by __cache_set_unregister() during cleanup. This appears to happen only
during an OOM condition on bcache_register.
Signed-off-by: Eric Wheeler <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/md/bcache/super.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 70d396ee69e2..2a697b3d58c5 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1343,6 +1343,9 @@ static void cache_set_flush(struct closure *cl)
struct btree *b;
unsigned i;
+ if (!c)
+ closure_return(cl);
+
bch_cache_accounting_destroy(&c->accounting);
kobject_put(&c->internal);
--
2.8.1
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5c915c68763889f0183a1cc61c84bb228b60124a upstream.
On my bttv card "Hauppauge WinTV [card=10]" capturing in YV12 fmt at max
size results in a solid green rectangle being captured (all colors 0 in
YUV).
This turns out to be caused by max-width (924) not being a multiple of 16.
We've likely never hit this problem before since normally xawtv / tvtime,
etc. will prefer packed pixel formats. But when using a video card which
is using xf86-video-modesetting + glamor, only planar XVideo fmts are
available, and xawtv will chose a matching capture format to avoid needing
to do conversion, triggering the solid green window problem.
Signed-off-by: Hans de Goede <[email protected]>
Acked-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/pci/bt8xx/bttv-driver.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c
index 4f0aaa51ae0d..253f66e2eb4b 100644
--- a/drivers/media/pci/bt8xx/bttv-driver.c
+++ b/drivers/media/pci/bt8xx/bttv-driver.c
@@ -2333,6 +2333,19 @@ static int bttv_g_fmt_vid_overlay(struct file *file, void *priv,
return 0;
}
+static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt,
+ unsigned int *width_mask,
+ unsigned int *width_bias)
+{
+ if (fmt->flags & FORMAT_FLAGS_PLANAR) {
+ *width_mask = ~15; /* width must be a multiple of 16 pixels */
+ *width_bias = 8; /* nearest */
+ } else {
+ *width_mask = ~3; /* width must be a multiple of 4 pixels */
+ *width_bias = 2; /* nearest */
+ }
+}
+
static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
@@ -2342,6 +2355,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
enum v4l2_field field;
__s32 width, height;
__s32 height2;
+ unsigned int width_mask, width_bias;
int rc;
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
@@ -2374,9 +2388,9 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
width = f->fmt.pix.width;
height = f->fmt.pix.height;
+ bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
rc = limit_scaled_size_lock(fh, &width, &height, field,
- /* width_mask: 4 pixels */ ~3,
- /* width_bias: nearest */ 2,
+ width_mask, width_bias,
/* adjust_size */ 1,
/* adjust_crop */ 0);
if (0 != rc)
@@ -2409,6 +2423,7 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
__s32 width, height;
+ unsigned int width_mask, width_bias;
enum v4l2_field field;
retval = bttv_switch_type(fh, f->type);
@@ -2423,9 +2438,10 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
height = f->fmt.pix.height;
field = f->fmt.pix.field;
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias);
retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field,
- /* width_mask: 4 pixels */ ~3,
- /* width_bias: nearest */ 2,
+ width_mask, width_bias,
/* adjust_size */ 1,
/* adjust_crop */ 1);
if (0 != retval)
@@ -2433,8 +2449,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.field = field;
- fmt = format_by_fourcc(f->fmt.pix.pixelformat);
-
/* update our state informations */
fh->fmt = fmt;
fh->cap.field = f->fmt.pix.field;
--
2.8.1
From: Vladis Dronov <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 836b34a935abc91e13e63053d0a83b24dfb5ea78 upstream.
create_fixed_stream_quirk(), snd_usb_parse_audio_interface() and
create_uaxx_quirk() functions allocate the audioformat object by themselves
and free it upon error before returning. However, once the object is linked
to a stream, it's freed again in snd_usb_audio_pcm_free(), thus it'll be
double-freed, eventually resulting in a memory corruption.
This patch fixes these failures in the error paths by unlinking the audioformat
object before freeing it.
Based on a patch by Takashi Iwai <[email protected]>
[Note for stable backports:
this patch requires the commit 902eb7fd1e4a ('ALSA: usb-audio: Minor
code cleanup in create_fixed_stream_quirk()')]
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1283358
Reported-by: Ralf Spenneberg <[email protected]>
Signed-off-by: Vladis Dronov <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/usb/quirks.c | 4 ++++
sound/usb/stream.c | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a8bf7ed351fc..fa3893106b4c 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -138,6 +138,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
snd_printk(KERN_ERR "cannot memdup\n");
return -ENOMEM;
}
+ INIT_LIST_HEAD(&fp->list);
if (fp->nr_rates > MAX_NR_RATES) {
kfree(fp);
return -EINVAL;
@@ -181,6 +182,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
return 0;
error:
+ list_del(&fp->list); /* unlink for avoiding double-free */
kfree(fp);
kfree(rate_table);
return err;
@@ -456,6 +458,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
fp->datainterval = 0;
fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+ INIT_LIST_HEAD(&fp->list);
switch (fp->maxpacksize) {
case 0x120:
@@ -479,6 +482,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
err = snd_usb_add_audio_stream(chip, stream, fp);
if (err < 0) {
+ list_del(&fp->list); /* unlink for avoiding double-free */
kfree(fp);
return err;
}
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index c4339f97226b..cd8dd2865ef0 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -307,7 +307,9 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
/*
* add this endpoint to the chip instance.
* if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
+ * if not, create a new pcm stream. note, fp is added to the substream
+ * fmt_list and will be freed on the chip instance release. do not free
+ * fp or do remove it from the substream fmt_list to avoid double-free.
*/
int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
int stream,
@@ -653,6 +655,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
fp->clock = clock;
fp->chmap = convert_chmap(num_channels, chconfig, protocol);
+ INIT_LIST_HEAD(&fp->list);
/* some quirks for attributes here */
@@ -697,6 +700,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint);
err = snd_usb_add_audio_stream(chip, stream, fp);
if (err < 0) {
+ list_del(&fp->list); /* unlink for avoiding double-free */
kfree(fp->rate_table);
kfree(fp->chmap);
kfree(fp);
--
2.8.1
From: Tiffany Lin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7df5ab8774aa383c6d2bff00688d004585d96dfd upstream.
In v4l2-compliance utility, test QUERYBUF required correct length
value to go through each planar to check planar's length in
multi-planar buffer type
Signed-off-by: Tiffany Lin <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 2bece37d0228..61c2cd3be109 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -392,7 +392,8 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
get_user(kp->index, &up->index) ||
get_user(kp->type, &up->type) ||
get_user(kp->flags, &up->flags) ||
- get_user(kp->memory, &up->memory))
+ get_user(kp->memory, &up->memory) ||
+ get_user(kp->length, &up->length))
return -EFAULT;
if (V4L2_TYPE_IS_OUTPUT(kp->type))
@@ -404,9 +405,6 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
return -EFAULT;
if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- if (get_user(kp->length, &up->length))
- return -EFAULT;
-
num_planes = kp->length;
if (num_planes == 0) {
kp->m.planes = NULL;
@@ -439,16 +437,14 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
- if (get_user(kp->length, &up->length) ||
- get_user(kp->m.offset, &up->m.offset))
+ if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_USERPTR:
{
compat_long_t tmp;
- if (get_user(kp->length, &up->length) ||
- get_user(tmp, &up->m.userptr))
+ if (get_user(tmp, &up->m.userptr))
return -EFAULT;
kp->m.userptr = (unsigned long)compat_ptr(tmp);
@@ -490,7 +486,8 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
put_user(kp->sequence, &up->sequence) ||
put_user(kp->reserved2, &up->reserved2) ||
- put_user(kp->reserved, &up->reserved))
+ put_user(kp->reserved, &up->reserved) ||
+ put_user(kp->length, &up->length))
return -EFAULT;
if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
@@ -513,13 +510,11 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
} else {
switch (kp->memory) {
case V4L2_MEMORY_MMAP:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.offset, &up->m.offset))
+ if (put_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_USERPTR:
- if (put_user(kp->length, &up->length) ||
- put_user(kp->m.userptr, &up->m.userptr))
+ if (put_user(kp->m.userptr, &up->m.userptr))
return -EFAULT;
break;
case V4L2_MEMORY_OVERLAY:
--
2.8.1
From: Radim Krčmář <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7dd0fdff145c5be7146d0ac06732ae3613412ac1 upstream.
Discard policy uses ack_notifiers to prevent injection of PIT interrupts
before EOI from the last one.
This patch changes the policy to always try to deliver the interrupt,
which makes a difference when its vector is in ISR.
Old implementation would drop the interrupt, but proposed one injects to
IRR, like real hardware would.
The old policy breaks legacy NMI watchdogs, where PIT is used through
virtual wire (LVT0): PIT never sends an interrupt before receiving EOI,
thus a guest deadlock with disabled interrupts will stop NMIs.
Note that NMI doesn't do EOI, so PIT also had to send a normal interrupt
through IOAPIC. (KVM's PIT is deeply rotten and luckily not used much
in modern systems.)
Even though there is a chance of regressions, I think we can fix the
LVT0 NMI bug without introducing a new tick policy.
Reported-by: Yuki Shibuya <[email protected]>
Reviewed-by: Paolo Bonzini <[email protected]>
Signed-off-by: Radim Krčmář <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/i8254.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 1406ffde3e35..b0a706d063cb 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -244,7 +244,7 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
* PIC is being reset. Handle it gracefully here
*/
atomic_inc(&ps->pending);
- else if (value > 0)
+ else if (value > 0 && ps->reinject)
/* in this case, we had multiple outstanding pit interrupts
* that we needed to inject. Reinject
*/
@@ -287,7 +287,9 @@ static void pit_do_work(struct kthread_work *work)
* last one has been acked.
*/
spin_lock(&ps->inject_lock);
- if (ps->irq_ack) {
+ if (!ps->reinject)
+ inject = 1;
+ else if (ps->irq_ack) {
ps->irq_ack = 0;
inject = 1;
}
@@ -316,10 +318,10 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
struct kvm_kpit_state *ps = container_of(data, struct kvm_kpit_state, timer);
struct kvm_pit *pt = ps->kvm->arch.vpit;
- if (ps->reinject || !atomic_read(&ps->pending)) {
+ if (ps->reinject)
atomic_inc(&ps->pending);
- queue_kthread_work(&pt->worker, &pt->expired);
- }
+
+ queue_kthread_work(&pt->worker, &pt->expired);
if (ps->is_periodic) {
hrtimer_add_expires_ns(&ps->timer, ps->period);
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1f7c6658962fa1260c1658d681bd6bb0c746b99a upstream.
Cirrus HD-audio driver may adjust GPIO pins for EAPD dynamically
depending on the jack plug state. This works fine for the auto-mute
mode where the speaker gets muted upon the HP jack plug. OTOH, when
the auto-mute mode is off, this turns off the EAPD unexpectedly
depending on the jack state, which results in the silent speaker
output.
This patch fixes the silent speaker output issue by setting GPIO bits
constantly when the auto-mute mode is off.
Reported-and-tested-by: [email protected]
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/pci/hda/patch_cirrus.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index eef182bea2ad..6d8151d949ca 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -177,8 +177,12 @@ static void cs_automute(struct hda_codec *codec)
snd_hda_gen_update_outputs(codec);
if (spec->gpio_eapd_hp || spec->gpio_eapd_speaker) {
- spec->gpio_data = spec->gen.hp_jack_present ?
- spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+ if (spec->gen.automute_speaker)
+ spec->gpio_data = spec->gen.hp_jack_present ?
+ spec->gpio_eapd_hp : spec->gpio_eapd_speaker;
+ else
+ spec->gpio_data =
+ spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
snd_hda_codec_write(codec, 0x01, 0,
AC_VERB_SET_GPIO_DATA, spec->gpio_data);
}
--
2.8.1
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3e71da19f9dc22e39a755d6ae9678661abb66adc upstream.
bytesperline should be the bytesperline for the first plane for planar
formats, not that of all planes combined.
This fixes a crash in xawtv caused by the wrong bpl.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1305389
Reported-and-tested-by: Stas Sergeev <[email protected]>
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/pci/saa7134/saa7134-video.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index fb60da85bc2c..d11fdfbac275 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1562,10 +1562,13 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv,
f->fmt.pix.height = dev->height;
f->fmt.pix.field = fh->cap.field;
f->fmt.pix.pixelformat = dev->fmt->fourcc;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * dev->fmt->depth) >> 3;
+ if (dev->fmt->planar)
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ else
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * dev->fmt->depth) / 8;
f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
+ (f->fmt.pix.height * f->fmt.pix.width * dev->fmt->depth) / 8;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.priv = 0;
return 0;
@@ -1646,10 +1649,13 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv,
if (f->fmt.pix.height > maxh)
f->fmt.pix.height = maxh;
f->fmt.pix.width &= ~0x03;
- f->fmt.pix.bytesperline =
- (f->fmt.pix.width * fmt->depth) >> 3;
+ if (fmt->planar)
+ f->fmt.pix.bytesperline = f->fmt.pix.width;
+ else
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * fmt->depth) / 8;
f->fmt.pix.sizeimage =
- f->fmt.pix.height * f->fmt.pix.bytesperline;
+ (f->fmt.pix.height * f->fmt.pix.width * fmt->depth) / 8;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.priv = 0;
--
2.8.1
From: Martyn Welch <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cddc9434e3dcc37a85c4412fb8e277d3a582e456 upstream.
The CP2105 is used in the GE Healthcare Remote Alarm Box, with the
Manufacturer ID of 0x1901 and Product ID of 0x0194.
Signed-off-by: Martyn Welch <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/cp210x.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 26bcd501f314..bab76bc1e525 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -164,6 +164,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
{ USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
{ USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
+ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
--
2.8.1
From: Sebastian Frias <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0b41ce991052022c030fd868e03877700220b090 upstream.
Some UART HW has a single register combining UART_DLL/UART_DLM
(this was probably forgotten in the change that introduced the
callbacks, commit b32b19b8ffc05cbd3bf91c65e205f6a912ca15d9)
Fixes: b32b19b8ffc0 ("[SERIAL] 8250: set divisor register correctly ...")
Signed-off-by: Sebastian Frias <[email protected]>
Reviewed-by: Peter Hurley <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/tty/serial/8250/8250_core.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 04c8772639d3..a9eb91c51884 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -686,22 +686,16 @@ static int size_fifo(struct uart_8250_port *up)
*/
static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
{
- unsigned char old_dll, old_dlm, old_lcr;
- unsigned int id;
+ unsigned char old_lcr;
+ unsigned int id, old_dl;
old_lcr = serial_in(p, UART_LCR);
serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
+ old_dl = serial_dl_read(p);
+ serial_dl_write(p, 0);
+ id = serial_dl_read(p);
+ serial_dl_write(p, old_dl);
- old_dll = serial_in(p, UART_DLL);
- old_dlm = serial_in(p, UART_DLM);
-
- serial_out(p, UART_DLL, 0);
- serial_out(p, UART_DLM, 0);
-
- id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
-
- serial_out(p, UART_DLL, old_dll);
- serial_out(p, UART_DLM, old_dlm);
serial_out(p, UART_LCR, old_lcr);
return id;
--
2.8.1
From: Johan Hovold <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cac9b50b0d75a1d50d6c056ff65c005f3224c8e0 upstream.
Fix null-pointer dereference at probe should a (malicious) Treo device
lack the expected endpoints.
Specifically, the Treo port-setup hack was dereferencing the bulk-in and
interrupt-in urbs without first making sure they had been allocated by
core.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/visor.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 9c61a8671721..605068e6acf2 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -551,6 +551,11 @@ static int treo_attach(struct usb_serial *serial)
(serial->num_interrupt_in == 0))
return 0;
+ if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
/*
* It appears that Treos and Kyoceras want to use the
* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
--
2.8.1
From: Dmitry Tunin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 81d90442eac779938217c3444b240aa51fd3db47 upstream.
T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=03 Dev#= 5 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=04ca ProdID=3014 Rev=00.02
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
BugLink: https://bugs.launchpad.net/bugs/1546694
Signed-off-by: Dmitry Tunin <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 15d8dff3a95d..fd6fe53755f9 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -92,6 +92,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x04CA, 0x300d) },
{ USB_DEVICE(0x04CA, 0x300f) },
{ USB_DEVICE(0x04CA, 0x3010) },
+ { USB_DEVICE(0x04CA, 0x3014) },
{ USB_DEVICE(0x0930, 0x0219) },
{ USB_DEVICE(0x0930, 0x021c) },
{ USB_DEVICE(0x0930, 0x0220) },
@@ -154,6 +155,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index d75fd73426f7..72b6a577241f 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -169,6 +169,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
--
2.8.1
From: Dmitry Tunin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 75c6aca4765dbe3d0c1507ab5052f2e373dc2331 upstream.
T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 4 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3472 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
BugLink: https://bugs.launchpad.net/bugs/1552925
Signed-off-by: Dmitry Tunin <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index fd6fe53755f9..2a3e5ffbbf40 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -119,6 +119,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3423) },
{ USB_DEVICE(0x13d3, 0x3432) },
+ { USB_DEVICE(0x13d3, 0x3472) },
{ USB_DEVICE(0x13d3, 0x3474) },
/* Atheros AR5BBU12 with sflash firmware */
@@ -183,6 +184,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 72b6a577241f..7c9ca5995424 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -196,6 +196,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
--
2.8.1
From: Dmitry Tunin <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 609574eb46335cfac1421a07c0505627cbbab1f0 upstream.
T: Bus=03 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0
D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
P: Vendor=13d3 ProdID=3395 Rev=00.01
C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
BugLink: https://bugs.launchpad.net/bugs/1542564
Reported-and-tested-by: Christopher Simerly <[email protected]>
Signed-off-by: Dmitry Tunin <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/bluetooth/ath3k.c | 2 ++
drivers/bluetooth/btusb.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 63a1b21440ea..15d8dff3a95d 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -113,6 +113,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x13d3, 0x3393) },
+ { USB_DEVICE(0x13d3, 0x3395) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3423) },
@@ -175,6 +176,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 2f8d8992a3f4..d75fd73426f7 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -190,6 +190,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
+ { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0f886ca12765d20124bd06291c82951fd49a33be upstream.
create_fixed_stream_quirk() may cause a NULL-pointer dereference by
accessing the non-existing endpoint when a USB device with a malformed
USB descriptor is used.
This patch avoids it simply by adding a sanity check of bNumEndpoints
before the accesses.
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/usb/quirks.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 81d7e6a9725e..88fd1c561a15 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -168,6 +168,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
}
alts = &iface->altsetting[fp->altset_idx];
altsd = get_iface_desc(alts);
+ if (altsd->bNumEndpoints < 1) {
+ kfree(fp);
+ kfree(rate_table);
+ return -EINVAL;
+ }
+
fp->protocol = altsd->bInterfaceProtocol;
if (fp->datainterval == 0)
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 902eb7fd1e4af3ac69b9b30f8373f118c92b9729 upstream.
Just a minor code cleanup: unify the error paths.
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/usb/quirks.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 88fd1c561a15..a8bf7ed351fc 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -155,23 +155,18 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
stream = (fp->endpoint & USB_DIR_IN)
? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
err = snd_usb_add_audio_stream(chip, stream, fp);
- if (err < 0) {
- kfree(fp);
- kfree(rate_table);
- return err;
- }
+ if (err < 0)
+ goto error;
if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
fp->altset_idx >= iface->num_altsetting) {
- kfree(fp);
- kfree(rate_table);
- return -EINVAL;
+ err = -EINVAL;
+ goto error;
}
alts = &iface->altsetting[fp->altset_idx];
altsd = get_iface_desc(alts);
if (altsd->bNumEndpoints < 1) {
- kfree(fp);
- kfree(rate_table);
- return -EINVAL;
+ err = -EINVAL;
+ goto error;
}
fp->protocol = altsd->bInterfaceProtocol;
@@ -184,6 +179,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
snd_usb_init_pitch(chip, fp->iface, alts, fp);
snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max);
return 0;
+
+ error:
+ kfree(fp);
+ kfree(rate_table);
+ return err;
}
static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 447d6275f0c21f6cc97a88b3a0c601436a4cdf2a upstream.
Add some sanity check codes before actually accessing the endpoint via
get_endpoint() in order to avoid the invalid access through a
malformed USB descriptor. Mostly just checking bNumEndpoints, but in
one place (snd_microii_spdif_default_get()), the validity of iface and
altsetting index is checked as well.
Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/usb/clock.c | 2 ++
sound/usb/endpoint.c | 3 +++
sound/usb/mixer_quirks.c | 4 ++++
sound/usb/pcm.c | 2 ++
4 files changed, 11 insertions(+)
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 86f80c60b21f..1329d7725196 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -283,6 +283,8 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface,
unsigned char data[3];
int err, crate;
+ if (get_iface_desc(alts)->bNumEndpoints < 1)
+ return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
/* if endpoint doesn't have sampling rate control, bail out */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index b0a0f2028319..c42a4c0e95da 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -410,6 +410,9 @@ exit_clear:
*
* New endpoints will be added to chip->ep_list and must be freed by
* calling snd_usb_endpoint_free().
+ *
+ * For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that
+ * bNumEndpoints > 1 beforehand.
*/
struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
struct usb_host_interface *alts,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index ca2d07378807..ee4b3b901bf5 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -1372,7 +1372,11 @@ static int snd_microii_spdif_default_get(struct snd_kcontrol *kcontrol,
/* use known values for that card: interface#1 altsetting#1 */
iface = usb_ifnum_to_if(mixer->chip->dev, 1);
+ if (!iface || iface->num_altsetting < 2)
+ return -EINVAL;
alts = &iface->altsetting[1];
+ if (get_iface_desc(alts)->bNumEndpoints < 1)
+ return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
err = snd_usb_ctl_msg(mixer->chip->dev,
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 98ca3540514f..1f498b1f88bd 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -159,6 +159,8 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface,
unsigned char data[1];
int err;
+ if (get_iface_desc(alts)->bNumEndpoints < 1)
+ return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
data[0] = 1;
--
2.8.1
From: Josh Boyer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9c6ba456711687b794dcf285856fc14e2c76074f upstream.
The powermate driver expects at least one valid USB endpoint in its
probe function. If given malicious descriptors that specify 0 for
the number of endpoints, it will crash. Validate the number of
endpoints on the interface before using them.
The full report for this issue can be found here:
http://seclists.org/bugtraq/2016/Mar/85
Reported-by: Ralf Spenneberg <[email protected]>
Signed-off-by: Josh Boyer <[email protected]>
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/input/misc/powermate.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index 49c0c3ebd321..21ce1cf757bb 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -308,6 +308,9 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
int error = -ENOMEM;
interface = intf->cur_altsetting;
+ if (interface->desc.bNumEndpoints < 1)
+ return -EINVAL;
+
endpoint = &interface->endpoint[0].desc;
if (!usb_endpoint_is_int_in(endpoint))
return -EIO;
--
2.8.1
From: Bjørn Mork <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d48d5691ebf88a15d95ba96486917ffc79256536 upstream.
Thomas reports:
"Windows:
00 diagnostics
01 modem
02 at-port
03 nmea
04 nic
Linux:
T: Bus=02 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=2001 ProdID=7e19 Rev=02.32
S: Manufacturer=Mobile Connect
S: Product=Mobile Connect
S: SerialNumber=0123456789ABCDEF
C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I: If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage"
Reported-by: Thomas Schäfer <[email protected]>
Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/option.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 24366a2afea6..99c89d7fa1ad 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1818,6 +1818,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c55aee1bf0e6b6feec8b2927b43f7a09a6d5f754 upstream.
An attack using missing endpoints exists.
CVE-2016-3137
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/cypress_m8.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 558605d646f3..ba96eeed1bab 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -449,6 +449,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
struct usb_serial *serial = port->serial;
struct cypress_private *priv;
+ if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+ dev_err(&port->dev, "required endpoint is missing\n");
+ return -ENODEV;
+ }
+
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -608,12 +613,6 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
cypress_set_termios(tty, port, &priv->tmp_termios);
/* setup the port and start reading from the device */
- if (!port->interrupt_in_urb) {
- dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
- __func__);
- return -1;
- }
-
usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer,
--
2.8.1
From: Hans de Goede <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7445e45d19a09e5269dc85f17f9635be29d2f76c upstream.
SPC 880NC PC camera discussions:
http://www.pclinuxos.com/forum/index.php/topic,135688.0.html
Reported-by: Kikim <[email protected]>
Signed-off-by: Hans de Goede <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/usb/pwc/pwc-if.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c
index 77bbf7889659..db1e8ee13ded 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -91,6 +91,7 @@ static const struct usb_device_id pwc_device_table [] = {
{ USB_DEVICE(0x0471, 0x0312) },
{ USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */
{ USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */
+ { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */
{ USB_DEVICE(0x069A, 0x0001) }, /* Askey */
{ USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */
{ USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */
@@ -799,6 +800,11 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
name = "Philips SPC 900NC webcam";
type_id = 740;
break;
+ case 0x032C:
+ PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
+ name = "Philips SPC 880NC webcam";
+ type_id = 740;
+ break;
default:
return -ENODEV;
break;
--
2.8.1
From: Josh Boyer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit ea6db90e750328068837bed34cb1302b7a177339 upstream.
A Fedora user reports that the ftdi_sio driver works properly for the
ICP DAS I-7561U device. Further, the user manual for these devices
instructs users to load the driver and add the ids using the sysfs
interface.
Add support for these in the driver directly so that the devices work
out of the box instead of needing manual configuration.
Reported-by: <[email protected]>
Signed-off-by: Josh Boyer <[email protected]>
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/ftdi_sio.c | 4 ++++
drivers/usb/serial/ftdi_sio_ids.h | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index b009e42f2624..25206e043b85 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1018,6 +1018,10 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) },
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) },
{ USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) },
+ /* ICP DAS I-756xU devices */
+ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) },
+ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index 7850071c0ae1..334bc600282d 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -872,6 +872,14 @@
#define NOVITUS_BONO_E_PID 0x6010
/*
+ * ICPDAS I-756*U devices
+ */
+#define ICPDAS_VID 0x1b5c
+#define ICPDAS_I7560U_PID 0x0103
+#define ICPDAS_I7561U_PID 0x0104
+#define ICPDAS_I7563U_PID 0x0105
+
+/*
* RT Systems programming cables for various ham radios
*/
#define RTSYSTEMS_VID 0x2100 /* Vendor ID */
--
2.8.1
From: Bjorn Helgaas <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b84106b4e2290c081cdab521fa832596cdfea246 upstream.
The PCI config header (first 64 bytes of each device's config space) is
defined by the PCI spec so generic software can identify the device and
manage its usage of I/O, memory, and IRQ resources.
Some non-spec-compliant devices put registers other than BARs where the
BARs should be. When the PCI core sizes these "BARs", the reads and writes
it does may have unwanted side effects, and the "BAR" may appear to
describe non-sensical address space.
Add a flag bit to mark non-compliant devices so we don't touch their BARs.
Turn off IO/MEM decoding to prevent the devices from consuming address
space, since we can't read the BARs to find out what that address space
would be.
Signed-off-by: Bjorn Helgaas <[email protected]>
Tested-by: Andi Kleen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/pci/probe.c | 14 ++++++++++++++
include/linux/pci.h | 1 +
2 files changed, 15 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 16b3bd684942..51379906c69c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -175,6 +175,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct pci_bus_region region, inverted_region;
bool bar_too_big = false, bar_disabled = false;
+ if (dev->non_compliant_bars)
+ return 0;
+
mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
/* No printks while decoding is disabled! */
@@ -1019,6 +1022,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
int pci_setup_device(struct pci_dev *dev)
{
u32 class;
+ u16 cmd;
u8 hdr_type;
struct pci_slot *slot;
int pos = 0;
@@ -1066,6 +1070,16 @@ int pci_setup_device(struct pci_dev *dev)
/* device class may be changed after fixup */
class = dev->class >> 8;
+ if (dev->non_compliant_bars) {
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+ dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+ cmd &= ~PCI_COMMAND_IO;
+ cmd &= ~PCI_COMMAND_MEMORY;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ }
+
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
if (class == PCI_CLASS_BRIDGE_PCI)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b11e6e280f15..81562314df8c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -345,6 +345,7 @@ struct pci_dev {
unsigned int __aer_firmware_first:1;
unsigned int broken_intx_masking:1;
unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */
+ unsigned int non_compliant_bars:1; /* broken BARs; ignore them */
pci_dev_flags_t dev_flags;
atomic_t enable_cnt; /* pci_enable_device has been called */
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5a07975ad0a36708c6b0a5b9fea1ff811d0b0c1f upstream.
The driver can be crashed with devices that expose crafted descriptors
with too few endpoints.
See: http://seclists.org/bugtraq/2016/Mar/61
Signed-off-by: Oliver Neukum <[email protected]>
[johan: fix OOB endpoint check and add error messages ]
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/digi_acceleport.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 19b467fe0388..fd525134666b 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -1253,8 +1253,27 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
static int digi_startup(struct usb_serial *serial)
{
+ struct device *dev = &serial->interface->dev;
struct digi_serial *serial_priv;
int ret;
+ int i;
+
+ /* check whether the device has the expected number of endpoints */
+ if (serial->num_port_pointers < serial->type->num_ports + 1) {
+ dev_err(dev, "OOB endpoints missing\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < serial->type->num_ports + 1 ; i++) {
+ if (!serial->port[i]->read_urb) {
+ dev_err(dev, "bulk-in endpoint missing\n");
+ return -ENODEV;
+ }
+ if (!serial->port[i]->write_urb) {
+ dev_err(dev, "bulk-out endpoint missing\n");
+ return -ENODEV;
+ }
+ }
serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
if (!serial_priv)
--
2.8.1
From: Josh Boyer <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4ec0ef3a82125efc36173062a50624550a900ae0 upstream.
The iowarrior driver expects at least one valid endpoint. If given
malicious descriptors that specify 0 for the number of endpoints,
it will crash in the probe function. Ensure there is at least
one endpoint on the interface before using it.
The full report of this issue can be found here:
http://seclists.org/bugtraq/2016/Mar/87
Reported-by: Ralf Spenneberg <[email protected]>
Signed-off-by: Josh Boyer <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/misc/iowarrior.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index d36f34e25bed..4c24ba0a6574 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -792,6 +792,12 @@ static int iowarrior_probe(struct usb_interface *interface,
iface_desc = interface->cur_altsetting;
dev->product_id = le16_to_cpu(udev->descriptor.idProduct);
+ if (iface_desc->desc.bNumEndpoints < 1) {
+ dev_err(&interface->dev, "Invalid number of endpoints\n");
+ retval = -EINVAL;
+ goto error;
+ }
+
/* set up the endpoint information */
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0b818e3956fc1ad976bee791eadcbb3b5fec5bfd upstream.
Attacks that trick drivers into passing a NULL pointer
to usb_driver_claim_interface() using forged descriptors are
known. This thwarts them by sanity checking.
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/core/driver.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index bfddeb3bc97e..8053fab9ae69 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -463,11 +463,15 @@ static int usb_unbind_interface(struct device *dev)
int usb_driver_claim_interface(struct usb_driver *driver,
struct usb_interface *iface, void *priv)
{
- struct device *dev = &iface->dev;
+ struct device *dev;
struct usb_device *udev;
int retval = 0;
int lpm_disable_error;
+ if (!iface)
+ return -ENODEV;
+
+ dev = &iface->dev;
if (dev->driver)
return -EBUSY;
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4e9a0b05257f29cf4b75f3209243ed71614d062e upstream.
An attack using the lack of sanity checking in probe is known. This
patch checks for the existence of a second port.
CVE-2016-3136
Signed-off-by: Oliver Neukum <[email protected]>
[johan: add error message ]
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/serial/mct_u232.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 6a15adf53360..c14c29ff1151 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -377,14 +377,21 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port,
static int mct_u232_port_probe(struct usb_serial_port *port)
{
+ struct usb_serial *serial = port->serial;
struct mct_u232_private *priv;
+ /* check first to simplify error handling */
+ if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
+ dev_err(&port->dev, "expected endpoint missing\n");
+ return -ENODEV;
+ }
+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* Use second interrupt-in endpoint for reading. */
- priv->read_urb = port->serial->port[1]->interrupt_in_urb;
+ priv->read_urb = serial->port[1]->interrupt_in_urb;
priv->read_urb->context = port;
spin_lock_init(&priv->lock);
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0d5ce778c43bf888328231bcdce05d5c860655aa upstream.
A typo of j for i led to a logic bug. To rule out future
confusion, the variable names are made meaningful.
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/core/hub.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 066e9af4d4db..0519b6f5b86f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4064,7 +4064,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
- int i, j, retval;
+ int retries, operations, retval, i;
unsigned delay = HUB_SHORT_RESET_TIME;
enum usb_device_speed oldspeed = udev->speed;
const char *speed;
@@ -4166,7 +4166,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
* first 8 bytes of the device descriptor to get the ep0 maxpacket
* value.
*/
- for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) {
+ for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) {
if (USE_NEW_SCHEME(retry_counter) && !(hcd->driver->flags & HCD_USB3)) {
struct usb_device_descriptor *buf;
int r = 0;
@@ -4182,7 +4182,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
* 255 is for WUSB devices, we actually need to use
* 512 (WUSB1.0[4.8.1]).
*/
- for (j = 0; j < 3; ++j) {
+ for (operations = 0; operations < 3; ++operations) {
buf->bMaxPacketSize0 = 0;
r = usb_control_msg(udev, usb_rcvaddr0pipe(),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
@@ -4208,7 +4208,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
* reset. But only on the first attempt,
* lest we get into a time out/reset loop
*/
- if (r == 0 || (r == -ETIMEDOUT && j == 0))
+ if (r == 0 || (r == -ETIMEDOUT && retries == 0))
break;
}
udev->descriptor.bMaxPacketSize0 =
@@ -4240,7 +4240,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
* authorization will assign the final address.
*/
if (udev->wusb == 0) {
- for (j = 0; j < SET_ADDRESS_TRIES; ++j) {
+ for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) {
retval = hub_set_address(udev, devnum);
if (retval >= 0)
break;
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8835ba4a39cf53f705417b3b3a94eb067673f2c9 upstream.
An attack has become available which pretends to be a quirky
device circumventing normal sanity checks and crashes the kernel
by an insufficient number of interfaces. This patch adds a check
to the code path for quirky devices.
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/class/cdc-acm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index c0ed832d8ad5..ba6b978d9de4 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -989,6 +989,9 @@ static int acm_probe(struct usb_interface *intf,
if (quirks == NO_UNION_NORMAL) {
data_interface = usb_ifnum_to_if(usb_dev, 1);
control_interface = usb_ifnum_to_if(usb_dev, 0);
+ /* we would crash */
+ if (!data_interface || !control_interface)
+ return -ENODEV;
goto skip_normal_probe;
}
--
2.8.1
From: Oliver Neukum <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 264904ccc33c604d4b3141bbd33808152dfac45b upstream.
Some devices I got show an inability to operate right after
power on if they are already connected. They are beyond recovery
if the descriptors are requested multiple times. So in case of
a timeout we rather bail early and reset again. But it must be
done only on the first loop lest we get into a reset/time out
spiral that can be overcome with a retry.
This patch is a rework of a patch that fell through the cracks.
http://www.spinics.net/lists/linux-usb/msg103263.html
Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/core/hub.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index fdcf290a7bc3..066e9af4d4db 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4202,7 +4202,13 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
r = -EPROTO;
break;
}
- if (r == 0)
+ /*
+ * Some devices time out if they are powered on
+ * when already connected. They need a second
+ * reset. But only on the first attempt,
+ * lest we get into a time out/reset loop
+ */
+ if (r == 0 || (r == -ETIMEDOUT && j == 0))
break;
}
udev->descriptor.bMaxPacketSize0 =
--
2.8.1
From: Maurizio Lombardi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 84bd64993f916bcf86270c67686ecf4cea7b8933 upstream.
In beiscsi_setup_boot_info(), the boot_kset pointer should be set to
NULL in case of failure otherwise an invalid pointer dereference may
occur later.
Signed-off-by: Maurizio Lombardi <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Reviewed-by: Jitendra Bhivare <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/be2iscsi/be_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 86dcc5c10659..8eeb24272154 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4040,6 +4040,7 @@ put_shost:
scsi_host_put(phba->shost);
free_kset:
iscsi_boot_destroy_kset(phba->boot_kset);
+ phba->boot_kset = NULL;
return -ENOMEM;
}
--
2.8.1
From: "[email protected]" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c5967b79ecabe2baca40658d9073e28b30d7f6cf upstream.
This patch adds missing AHCI RAID SATA Device IDs for the Intel Sunrise
Point PCH.
Signed-off-by: Nanda Kishore Chinna <[email protected]>
Signed-off-by: Charles Rose <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/ata/ahci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index eda3eadd5830..36c839eba595 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -367,9 +367,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
+ { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
--
2.8.1
From: Dirk Brandewie <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c2294a2f7853e6450361d078b65407bdaa6d1d11 upstream.
Ensure that no timer callback is running since we are about to free
the timer structure. We cannot guarantee that the call back is called
on the CPU where the timer is running.
Reported-by: Thomas Gleixner <[email protected]>
Signed-off-by: Dirk Brandewie <[email protected]>
Reviewed-by: Srivatsa S. Bhat <[email protected]>
Acked-by: Viresh Kumar <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/cpufreq/intel_pstate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 132a9139c19f..a8056af80999 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -635,7 +635,7 @@ static int intel_pstate_cpu_exit(struct cpufreq_policy *policy)
{
int cpu = policy->cpu;
- del_timer(&all_cpu_data[cpu]->timer);
+ del_timer_sync(&all_cpu_data[cpu]->timer);
kfree(all_cpu_data[cpu]);
all_cpu_data[cpu] = NULL;
return 0;
--
2.8.1
From: Raghava Aditya Renukunta <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit f88fa79a61726ce9434df9b4aede36961f709f17 upstream.
aac_fib_map_free() calls pci_free_consistent() without checking that
dev->hw_fib_va is not NULL and dev->max_fib_size is not zero.If they are
indeed NULL/0, this will result in a hang as pci_free_consistent() will
attempt to invalidate cache for the entire 64-bit address space
(which would take a very long time).
Fixed by adding a check to make sure that dev->hw_fib_va and
dev->max_fib_size are not NULL and 0 respectively.
Fixes: 9ad5204d6 - "[SCSI]aacraid: incorrect dma mapping mask during blinked recover or user initiated reset"
Signed-off-by: Raghava Aditya Renukunta <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Reviewed-by: Tomas Henzl <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/aacraid/commsup.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index cab190af6345..6b32ddcefc11 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -83,9 +83,12 @@ static int fib_map_alloc(struct aac_dev *dev)
void aac_fib_map_free(struct aac_dev *dev)
{
- pci_free_consistent(dev->pdev,
- dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
- dev->hw_fib_va, dev->hw_fib_pa);
+ if (dev->hw_fib_va && dev->max_fib_size) {
+ pci_free_consistent(dev->pdev,
+ (dev->max_fib_size *
+ (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
+ dev->hw_fib_va, dev->hw_fib_pa);
+ }
dev->hw_fib_va = NULL;
dev->hw_fib_pa = 0;
}
--
2.8.1
From: Douglas Gilbert <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 upstream.
One of the strange things that the original sg driver did was let the
user provide both a data-out buffer (it followed the sg_header+cdb)
_and_ specify a reply length greater than zero. What happened was that
the user data-out buffer was copied into some kernel buffers and then
the mid level was told a read type operation would take place with the
data from the device overwriting the same kernel buffers. The user would
then read those kernel buffers back into the user space.
>From what I can tell, the above action was broken by commit fad7f01e61bf
("sg: set dxferp to NULL for READ with the older SG interface") in 2008
and syzkaller found that out recently.
Make sure that a user space pointer is passed through when data follows
the sg_header structure and command. Fix the abnormal case when a
non-zero reply_len is also given.
Fixes: fad7f01e61bf737fe8a3740d803f000db57ecac6
Signed-off-by: Douglas Gilbert <[email protected]>
Reviewed-by: Ewan Milne <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/sg.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0be16bf5f0cd..1f65e32db285 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -633,7 +633,8 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
else
hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
hp->dxfer_len = mxsize;
- if (hp->dxfer_direction == SG_DXFER_TO_DEV)
+ if ((hp->dxfer_direction == SG_DXFER_TO_DEV) ||
+ (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV))
hp->dxferp = (char __user *)buf + cmd_size;
else
hp->dxferp = NULL;
--
2.8.1
From: Andy Lutomirski <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c29016cf41fe9fa994a5ecca607cf5f1cd98801e upstream.
iopl(3) is supposed to work if iopl is already 3, even if
unprivileged. This didn't work right on Xen PV. Fix it.
Reviewewd-by: Jan Beulich <[email protected]>
Signed-off-by: Andy Lutomirski <[email protected]>
Cc: Andrew Cooper <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Boris Ostrovsky <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: David Vrabel <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Jan Beulich <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Link: http://lkml.kernel.org/r/8ce12013e6e4c0a44a97e316be4a6faff31bd5ea.1458162709.git.luto@kernel.org
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/ioport.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 4ddaf66ea35f..792621a32457 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -96,9 +96,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
SYSCALL_DEFINE1(iopl, unsigned int, level)
{
struct pt_regs *regs = current_pt_regs();
- unsigned int old = (regs->flags >> 12) & 3;
struct thread_struct *t = ¤t->thread;
+ /*
+ * Careful: the IOPL bits in regs->flags are undefined under Xen PV
+ * and changing them has no effect.
+ */
+ unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT;
+
if (level > 3)
return -EINVAL;
/* Trying to gain more privileges? */
@@ -106,8 +111,9 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
}
- regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
- t->iopl = level << 12;
+ regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
+ (level << X86_EFLAGS_IOPL_BIT);
+ t->iopl = level << X86_EFLAGS_IOPL_BIT;
set_iopl_mask(t->iopl);
return 0;
--
2.8.1
From: Dan Carpenter <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 6f3508f61c814ee852c199988a62bd954c50dfc1 upstream.
dct_sel_base_off is declared as a u64 but we're only using the lower 32
bits because of a shift wrapping bug. This can possibly truncate the
upper 16 bits of DctSelBaseOffset[47:26], causing us to misdecode the CS
row.
Fixes: c8e518d5673d ('amd64_edac: Sanitize f10_get_base_addr_offset')
Signed-off-by: Dan Carpenter <[email protected]>
Cc: Aravind Gopalakrishnan <[email protected]>
Cc: linux-edac <[email protected]>
Link: http://lkml.kernel.org/r/20160120095451.GB19898@mwanda
Signed-off-by: Borislav Petkov <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/edac/amd64_edac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 7a7d5d5d7d6d..88da32477991 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -1301,7 +1301,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, u8 range,
u64 chan_off;
u64 dram_base = get_dram_base(pvt, range);
u64 hole_off = f10_dhar_offset(pvt);
- u64 dct_sel_base_off = (pvt->dct_sel_hi & 0xFFFFFC00) << 16;
+ u64 dct_sel_base_off = (u64)(pvt->dct_sel_hi & 0xFFFFFC00) << 16;
if (hi_rng) {
/*
--
2.8.1
From: Dave Jones <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 7834c10313fb823e538f2772be78edcdeed2e6e3 upstream.
Since 4.4, I've been able to trigger this occasionally:
===============================
[ INFO: suspicious RCU usage. ]
4.5.0-rc7-think+ #3 Not tainted
Cc: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
-------------------------------
./arch/x86/include/asm/msr-trace.h:47 suspicious rcu_dereference_check() usage!
other info that might help us debug this:
RCU used illegally from idle CPU!
rcu_scheduler_active = 1, debug_locks = 1
RCU used illegally from extended quiescent state!
no locks held by swapper/3/0.
stack backtrace:
CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.5.0-rc7-think+ #3
ffffffff92f821e0 1f3e5c340597d7fc ffff880468e07f10 ffffffff92560c2a
ffff880462145280 0000000000000001 ffff880468e07f40 ffffffff921376a6
ffffffff93665ea0 0000cc7c876d28da 0000000000000005 ffffffff9383dd60
Call Trace:
<IRQ> [<ffffffff92560c2a>] dump_stack+0x67/0x9d
[<ffffffff921376a6>] lockdep_rcu_suspicious+0xe6/0x100
[<ffffffff925ae7a7>] do_trace_write_msr+0x127/0x1a0
[<ffffffff92061c83>] native_apic_msr_eoi_write+0x23/0x30
[<ffffffff92054408>] smp_trace_call_function_interrupt+0x38/0x360
[<ffffffff92d1ca60>] trace_call_function_interrupt+0x90/0xa0
<EOI> [<ffffffff92ac5124>] ? cpuidle_enter_state+0x1b4/0x520
Move the entering_irq() call before ack_APIC_irq(), because entering_irq()
tells the RCU susbstems to end the extended quiescent state, so that the
following trace call in ack_APIC_irq() works correctly.
Suggested-by: Andi Kleen <[email protected]>
Fixes: 4787c368a9bc "x86/tracing: Add irq_enter/exit() in smp_trace_reschedule_interrupt()"
Signed-off-by: Dave Jones <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/x86/include/asm/apic.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 1d2091a226bc..29559831c94f 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -699,8 +699,8 @@ static inline void entering_irq(void)
static inline void entering_ack_irq(void)
{
- ack_APIC_irq();
entering_irq();
+ ack_APIC_irq();
}
static inline void exiting_irq(void)
--
2.8.1
From: Lukasz Odzioba <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cc904f9cf26dc455cffbdf6e7eb86717e047d8ff upstream.
A new limit selected arbitrarily as power of two greater than
required minimum for Xeon Phi processor (72 for Knights Landing).
Currently driver is not able to handle cores with core ID greater than 32.
Such attempt ends up with the following error in dmesg:
coretemp coretemp.0: Adding Core XXX failed
Signed-off-by: Lukasz Odzioba <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/hwmon/coretemp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 942509892895..bf5722d31f40 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -51,7 +51,7 @@ module_param_named(tjmax, force_tjmax, int, 0444);
MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
#define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */
-#define NUM_REAL_CORES 32 /* Number of Real cores per cpu */
+#define NUM_REAL_CORES 128 /* Number of Real cores per cpu */
#define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */
#define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */
#define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)
--
2.8.1
From: Andy Lutomirski <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit b7a584598aea7ca73140cb87b40319944dd3393f upstream.
On Xen PV, regs->flags doesn't reliably reflect IOPL and the
exit-to-userspace code doesn't change IOPL. We need to context
switch it manually.
I'm doing this without going through paravirt because this is
specific to Xen PV. After the dust settles, we can merge this with
the 32-bit code, tidy up the iopl syscall implementation, and remove
the set_iopl pvop entirely.
Fixes XSA-171.
Reviewewd-by: Jan Beulich <[email protected]>
Signed-off-by: Andy Lutomirski <[email protected]>
Cc: Andrew Cooper <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Boris Ostrovsky <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: David Vrabel <[email protected]>
Cc: Denys Vlasenko <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Jan Beulich <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Link: http://lkml.kernel.org/r/693c3bd7aeb4d3c27c92c622b7d0f554a458173c.1458162709.git.luto@kernel.org
Signed-off-by: Ingo Molnar <[email protected]>
[ kamal: backport to 3.19-stable: no X86_FEATURE_XENPV so just call
xen_pv_domain() directly ]
Acked-by: Andy Lutomirski <[email protected]>
Signed-off-by: Kamal Mostafa <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/include/asm/xen/hypervisor.h | 2 ++
arch/x86/kernel/process_64.c | 12 ++++++++++++
arch/x86/xen/enlighten.c | 2 +-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index d866959e5685..d2ad00a42234 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -57,4 +57,6 @@ static inline bool xen_x2apic_para_available(void)
}
#endif
+extern void xen_set_iopl_mask(unsigned mask);
+
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index f99825ea4f96..5d4f6ccbae35 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -49,6 +49,7 @@
#include <asm/syscalls.h>
#include <asm/debugreg.h>
#include <asm/switch_to.h>
+#include <asm/xen/hypervisor.h>
asmlinkage extern void ret_from_fork(void);
@@ -374,6 +375,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
__switch_to_xtra(prev_p, next_p, tss);
+#ifdef CONFIG_XEN
+ /*
+ * On Xen PV, IOPL bits in pt_regs->flags have no effect, and
+ * current_pt_regs()->flags may not match the current task's
+ * intended IOPL. We need to switch it manually.
+ */
+ if (unlikely(xen_pv_domain() &&
+ prev->iopl != next->iopl))
+ xen_set_iopl_mask(next->iopl);
+#endif
+
return prev_p;
}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b2de632861c2..7c8af5286549 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -955,7 +955,7 @@ static void xen_load_sp0(struct tss_struct *tss,
xen_mc_issue(PARAVIRT_LAZY_CPU);
}
-static void xen_set_iopl_mask(unsigned mask)
+void xen_set_iopl_mask(unsigned mask)
{
struct physdev_set_iopl set_iopl;
--
2.8.1
From: Paolo Bonzini <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e9ad4ec8379ad1ba6f68b8ca1c26b50b5ae0a327 upstream.
Moving the initialization earlier is needed in 4.6 because
kvm_arch_init_vm is now using mmu_lock, causing lockdep to
complain:
[ 284.440294] INFO: trying to register non-static key.
[ 284.445259] the code is fine but needs lockdep annotation.
[ 284.450736] turning off the locking correctness validator.
...
[ 284.528318] [<ffffffff810aecc3>] lock_acquire+0xd3/0x240
[ 284.533733] [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[ 284.541467] [<ffffffff81715581>] _raw_spin_lock+0x41/0x80
[ 284.546960] [<ffffffffa0305aa0>] ? kvm_page_track_register_notifier+0x20/0x60 [kvm]
[ 284.554707] [<ffffffffa0305aa0>] kvm_page_track_register_notifier+0x20/0x60 [kvm]
[ 284.562281] [<ffffffffa02ece70>] kvm_mmu_init_vm+0x20/0x30 [kvm]
[ 284.568381] [<ffffffffa02dbf7a>] kvm_arch_init_vm+0x1ea/0x200 [kvm]
[ 284.574740] [<ffffffffa02bff3f>] kvm_dev_ioctl+0xbf/0x4d0 [kvm]
However, it also helps fixing a preexisting problem, which is why this
patch is also good for stable kernels: kvm_create_vm was incrementing
current->mm->mm_count but not decrementing it at the out_err label (in
case kvm_init_mmu_notifier failed). The new initialization order makes
it possible to add the required mmdrop without adding a new error label.
Reported-by: Borislav Petkov <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
virt/kvm/kvm_main.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 235b3f0cc97e..f8a3dd96a37a 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -448,6 +448,16 @@ static struct kvm *kvm_create_vm(unsigned long type)
if (!kvm)
return ERR_PTR(-ENOMEM);
+ spin_lock_init(&kvm->mmu_lock);
+ atomic_inc(¤t->mm->mm_count);
+ kvm->mm = current->mm;
+ kvm_eventfd_init(kvm);
+ mutex_init(&kvm->lock);
+ mutex_init(&kvm->irq_lock);
+ mutex_init(&kvm->slots_lock);
+ atomic_set(&kvm->users_count, 1);
+ INIT_LIST_HEAD(&kvm->devices);
+
r = kvm_arch_init_vm(kvm, type);
if (r)
goto out_err_nodisable;
@@ -477,16 +487,6 @@ static struct kvm *kvm_create_vm(unsigned long type)
goto out_err;
}
- spin_lock_init(&kvm->mmu_lock);
- kvm->mm = current->mm;
- atomic_inc(&kvm->mm->mm_count);
- kvm_eventfd_init(kvm);
- mutex_init(&kvm->lock);
- mutex_init(&kvm->irq_lock);
- mutex_init(&kvm->slots_lock);
- atomic_set(&kvm->users_count, 1);
- INIT_LIST_HEAD(&kvm->devices);
-
r = kvm_init_mmu_notifier(kvm);
if (r)
goto out_err;
@@ -506,6 +506,7 @@ out_err_nodisable:
kfree(kvm->buses[i]);
kvfree(kvm->memslots);
kvm_arch_free_vm(kvm);
+ mmdrop(current->mm);
return ERR_PTR(r);
}
--
2.8.1
From: Eric Sandeen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9de67c3ba9ea961ba420573d56479d09d33a7587 upstream.
Today, if we perform an xfs_growfs which adds allocation groups,
mp->m_maxagi is not properly updated when the growfs is complete.
Therefore inodes will continue to be allocated only in the
AGs which existed prior to the growfs, and the new space
won't be utilized.
This is because of this path in xfs_growfs_data_private():
xfs_growfs_data_private
xfs_initialize_perag(mp, nagcount, &nagimax);
if (mp->m_flags & XFS_MOUNT_32BITINODES)
index = xfs_set_inode32(mp);
else
index = xfs_set_inode64(mp);
if (maxagi)
*maxagi = index;
where xfs_set_inode* iterates over the (old) agcount in
mp->m_sb.sb_agblocks, which has not yet been updated
in the growfs path. So "index" will be returned based on
the old agcount, not the new one, and new AGs are not available
for inode allocation.
Fix this by explicitly passing the proper AG count (which
xfs_initialize_perag() already has) down another level,
so that xfs_set_inode* can make the proper decision about
acceptable AGs for inode allocation in the potentially
newly-added AGs.
This has been broken since 3.7, when these two
xfs_set_inode* functions were added in commit 2d2194f.
Prior to that, we looped over "agcount" not sb_agblocks
in these calculations.
Signed-off-by: Eric Sandeen <[email protected]>
Reviewed-by: Brian Foster <[email protected]>
Signed-off-by: Dave Chinner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/xfs/xfs_mount.c | 4 ++--
fs/xfs/xfs_super.c | 20 +++++++++++++-------
fs/xfs/xfs_super.h | 4 ++--
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index dc602b564255..6df2d305d4b3 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -254,9 +254,9 @@ xfs_initialize_perag(
mp->m_flags &= ~XFS_MOUNT_32BITINODES;
if (mp->m_flags & XFS_MOUNT_32BITINODES)
- index = xfs_set_inode32(mp);
+ index = xfs_set_inode32(mp, agcount);
else
- index = xfs_set_inode64(mp);
+ index = xfs_set_inode64(mp, agcount);
if (maxagi)
*maxagi = index;
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 15188cc99449..c85735880301 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -602,8 +602,13 @@ xfs_max_file_offset(
return (((__uint64_t)pagefactor) << bitshift) - 1;
}
+/*
+ * xfs_set_inode32() and xfs_set_inode64() are passed an agcount
+ * because in the growfs case, mp->m_sb.sb_agcount is not updated
+ * yet to the potentially higher ag count.
+ */
xfs_agnumber_t
-xfs_set_inode32(struct xfs_mount *mp)
+xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
{
xfs_agnumber_t index = 0;
xfs_agnumber_t maxagi = 0;
@@ -625,10 +630,10 @@ xfs_set_inode32(struct xfs_mount *mp)
do_div(icount, sbp->sb_agblocks);
max_metadata = icount;
} else {
- max_metadata = sbp->sb_agcount;
+ max_metadata = agcount;
}
- for (index = 0; index < sbp->sb_agcount; index++) {
+ for (index = 0; index < agcount; index++) {
ino = XFS_AGINO_TO_INO(mp, index, agino);
if (ino > XFS_MAXINUMBER_32) {
@@ -653,11 +658,11 @@ xfs_set_inode32(struct xfs_mount *mp)
}
xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
{
xfs_agnumber_t index = 0;
- for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+ for (index = 0; index < agcount; index++) {
struct xfs_perag *pag;
pag = xfs_perag_get(mp, index);
@@ -1203,6 +1208,7 @@ xfs_fs_remount(
char *options)
{
struct xfs_mount *mp = XFS_M(sb);
+ xfs_sb_t *sbp = &mp->m_sb;
substring_t args[MAX_OPT_ARGS];
char *p;
int error;
@@ -1222,10 +1228,10 @@ xfs_fs_remount(
mp->m_flags &= ~XFS_MOUNT_BARRIER;
break;
case Opt_inode64:
- mp->m_maxagi = xfs_set_inode64(mp);
+ mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
break;
case Opt_inode32:
- mp->m_maxagi = xfs_set_inode32(mp);
+ mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
break;
default:
/*
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index bbe3d15a7904..b4cfe21d8fb0 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
extern void xfs_flush_inodes(struct xfs_mount *mp);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
extern const struct export_operations xfs_export_operations;
extern const struct xattr_handler *xfs_xattr_handlers[];
--
2.8.1
From: Martin Schwidefsky <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 3446c13b268af86391d06611327006b059b8bab1 upstream.
The fork of a process with four page table levels is broken since
git commit 6252d702c5311ce9 "[S390] dynamic page tables."
All new mm contexts are created with three page table levels and
an asce limit of 4TB. If the parent has four levels dup_mmap will
add vmas to the new context which are outside of the asce limit.
The subsequent call to copy_page_range will walk the three level
page table structure of the new process with non-zero pgd and pud
indexes. This leads to memory clobbers as the pgd_index *and* the
pud_index is added to the mm->pgd pointer without a pgd_deref
in between.
The init_new_context() function is selecting the number of page
table levels for a new context. The function is used by mm_init()
which in turn is called by dup_mm() and mm_alloc(). These two are
used by fork() and exec(). The init_new_context() function can
distinguish the two cases by looking at mm->context.asce_limit,
for fork() the mm struct has been copied and the number of page
table levels may not change. For exec() the mm_alloc() function
set the new mm structure to zero, in this case a three-level page
table is created as the temporary stack space is located at
STACK_TOP_MAX = 4TB.
This fixes CVE-2016-2143.
Reported-by: Marcin Kościelnicki <[email protected]>
Reviewed-by: Heiko Carstens <[email protected]>
Signed-off-by: Martin Schwidefsky <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/s390/include/asm/mmu_context.h | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 9f973d8de90e..f61e21848845 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -17,12 +17,15 @@ static inline int init_new_context(struct task_struct *tsk,
{
atomic_set(&mm->context.attach_count, 0);
mm->context.flush_mm = 0;
- mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+ mm->context.has_pgste = 0;
+ if (mm->context.asce_limit == 0) {
+ /* context created by exec, set asce limit to 4TB */
+ mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
#ifdef CONFIG_64BIT
- mm->context.asce_bits |= _ASCE_TYPE_REGION3;
+ mm->context.asce_bits |= _ASCE_TYPE_REGION3;
#endif
- mm->context.has_pgste = 0;
- mm->context.asce_limit = STACK_TOP_MAX;
+ mm->context.asce_limit = STACK_TOP_MAX;
+ }
crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
return 0;
}
@@ -75,10 +78,6 @@ static inline void activate_mm(struct mm_struct *prev,
static inline void arch_dup_mmap(struct mm_struct *oldmm,
struct mm_struct *mm)
{
-#ifdef CONFIG_64BIT
- if (oldmm->context.asce_limit < mm->context.asce_limit)
- crst_table_downgrade(mm, oldmm->context.asce_limit);
-#endif
}
static inline void arch_exit_mmap(struct mm_struct *mm)
--
2.8.1
From: Paolo Bonzini <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 2849eb4f99d54925c543db12917127f88b3c38ff upstream.
A guest executing an invalid invept instruction would hang
because the instruction pointer was not updated.
Fixes: bfd0a56b90005f8c8a004baf407ad90045c2b11e
Reviewed-by: David Matlack <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/vmx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 9e439266554d..92f9e2abf710 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6372,6 +6372,7 @@ static int handle_invept(struct kvm_vcpu *vcpu)
if (!(types & (1UL << type))) {
nested_vmx_failValid(vcpu,
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
+ skip_emulated_instruction(vcpu);
return 1;
}
--
2.8.1
From: Alan Stern <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e50293ef9775c5f1cf3fcc093037dd6a8c5684ea upstream.
Commit 8520f38099cc ("USB: change hub initialization sleeps to
delayed_work") changed the hub_activate() routine to make part of it
run in a workqueue. However, the commit failed to take a reference to
the usb_hub structure or to lock the hub interface while doing so. As
a result, if a hub is plugged in and quickly unplugged before the work
routine can run, the routine will try to access memory that has been
deallocated. Or, if the hub is unplugged while the routine is
running, the memory may be deallocated while it is in active use.
This patch fixes the problem by taking a reference to the usb_hub at
the start of hub_activate() and releasing it at the end (when the work
is finished), and by locking the hub interface while the work routine
is running. It also adds a check at the start of the routine to see
if the hub has already been disconnected, in which nothing should be
done.
Signed-off-by: Alan Stern <[email protected]>
Reported-by: Alexandru Cornea <[email protected]>
Tested-by: Alexandru Cornea <[email protected]>
Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work")
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/core/hub.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a7de5daae6d3..fdcf290a7bc3 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -114,6 +114,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
#define HUB_DEBOUNCE_STABLE 100
static int usb_reset_and_verify_device(struct usb_device *udev);
+static void hub_release(struct kref *kref);
static inline char *portspeed(struct usb_hub *hub, int portstatus)
{
@@ -1030,10 +1031,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
unsigned delay;
/* Continue a partial initialization */
- if (type == HUB_INIT2)
- goto init2;
- if (type == HUB_INIT3)
+ if (type == HUB_INIT2 || type == HUB_INIT3) {
+ device_lock(hub->intfdev);
+
+ /* Was the hub disconnected while we were waiting? */
+ if (hub->disconnected) {
+ device_unlock(hub->intfdev);
+ kref_put(&hub->kref, hub_release);
+ return;
+ }
+ if (type == HUB_INIT2)
+ goto init2;
goto init3;
+ }
+ kref_get(&hub->kref);
/* The superspeed hub except for root hub has to use Hub Depth
* value as an offset into the route string to locate the bits
@@ -1230,6 +1241,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
schedule_delayed_work(&hub->init_work,
msecs_to_jiffies(delay));
+ device_unlock(hub->intfdev);
return; /* Continues at init3: below */
} else {
msleep(delay);
@@ -1250,6 +1262,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
/* Allow autosuspend if it was suppressed */
if (type <= HUB_INIT3)
usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+
+ if (type == HUB_INIT2 || type == HUB_INIT3)
+ device_unlock(hub->intfdev);
+
+ kref_put(&hub->kref, hub_release);
}
/* Implement the continuations for the delays above */
--
2.8.1
From: Konrad Rzeszutek Wilk <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 8135cf8b092723dbfcc611fe6fdcb3a36c9951c5 upstream.
Double fetch vulnerabilities that happen when a variable is
fetched twice from shared memory but a security check is only
performed the first time.
The xen_pcibk_do_op function performs a switch statements on the op->cmd
value which is stored in shared memory. Interestingly this can result
in a double fetch vulnerability depending on the performed compiler
optimization.
This patch fixes it by saving the xen_pci_op command before
processing it. We also use 'barrier' to make sure that the
compiler does not perform any optimization.
This is part of XSA155.
Reviewed-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Jan Beulich <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Cc: "Jan Beulich" <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/xen/xen-pciback/pciback.h | 1 +
drivers/xen/xen-pciback/pciback_ops.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h
index f72af87640e0..560b3ecbcba8 100644
--- a/drivers/xen/xen-pciback/pciback.h
+++ b/drivers/xen/xen-pciback/pciback.h
@@ -37,6 +37,7 @@ struct xen_pcibk_device {
struct xen_pci_sharedinfo *sh_info;
unsigned long flags;
struct work_struct op_work;
+ struct xen_pci_op op;
};
struct xen_pcibk_dev_data {
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 1199d147dcde..a2da466d2333 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -331,9 +331,11 @@ void xen_pcibk_do_op(struct work_struct *data)
container_of(data, struct xen_pcibk_device, op_work);
struct pci_dev *dev;
struct xen_pcibk_dev_data *dev_data = NULL;
- struct xen_pci_op *op = &pdev->sh_info->op;
+ struct xen_pci_op *op = &pdev->op;
int test_intx = 0;
+ *op = pdev->sh_info->op;
+ barrier();
dev = xen_pcibk_get_pci_dev(pdev, op->domain, op->bus, op->devfn);
if (dev == NULL)
@@ -375,6 +377,17 @@ void xen_pcibk_do_op(struct work_struct *data)
if ((dev_data->enable_intx != test_intx))
xen_pcibk_control_isr(dev, 0 /* no reset */);
}
+ pdev->sh_info->op.err = op->err;
+ pdev->sh_info->op.value = op->value;
+#ifdef CONFIG_PCI_MSI
+ if (op->cmd == XEN_PCI_OP_enable_msix && op->err == 0) {
+ unsigned int i;
+
+ for (i = 0; i < op->value; i++)
+ pdev->sh_info->op.msix_entries[i].vector =
+ op->msix_entries[i].vector;
+ }
+#endif
/* Tell the driver domain that we're done. */
wmb();
clear_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags);
--
2.8.1
From: Daniel Borkmann <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 4c672e4b42bc8046d63a6eb0a2c6a450a501af32 upstream.
It has been reported that generating an MLD listener report on
devices with large MTUs (e.g. 9000) and a high number of IPv6
addresses can trigger a skb_over_panic():
skbuff: skb_over_panic: text:ffffffff80612a5d len:3776 put:20
head:ffff88046d751000 data:ffff88046d751010 tail:0xed0 end:0xec0
dev:port1
------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:100!
invalid opcode: 0000 [#1] SMP
Modules linked in: ixgbe(O)
CPU: 3 PID: 0 Comm: swapper/3 Tainted: G O 3.14.23+ #4
[...]
Call Trace:
<IRQ>
[<ffffffff80578226>] ? skb_put+0x3a/0x3b
[<ffffffff80612a5d>] ? add_grhead+0x45/0x8e
[<ffffffff80612e3a>] ? add_grec+0x394/0x3d4
[<ffffffff80613222>] ? mld_ifc_timer_expire+0x195/0x20d
[<ffffffff8061308d>] ? mld_dad_timer_expire+0x45/0x45
[<ffffffff80255b5d>] ? call_timer_fn.isra.29+0x12/0x68
[<ffffffff80255d16>] ? run_timer_softirq+0x163/0x182
[<ffffffff80250e6f>] ? __do_softirq+0xe0/0x21d
[<ffffffff8025112b>] ? irq_exit+0x4e/0xd3
[<ffffffff802214bb>] ? smp_apic_timer_interrupt+0x3b/0x46
[<ffffffff8063f10a>] ? apic_timer_interrupt+0x6a/0x70
mld_newpack() skb allocations are usually requested with dev->mtu
in size, since commit 72e09ad107e7 ("ipv6: avoid high order allocations")
we have changed the limit in order to be less likely to fail.
However, in MLD/IGMP code, we have some rather ugly AVAILABLE(skb)
macros, which determine if we may end up doing an skb_put() for
adding another record. To avoid possible fragmentation, we check
the skb's tailroom as skb->dev->mtu - skb->len, which is a wrong
assumption as the actual max allocation size can be much smaller.
The IGMP case doesn't have this issue as commit 57e1ab6eaddc
("igmp: refine skb allocations") stores the allocation size in
the cb[].
Set a reserved_tailroom to make it fit into the MTU and use
skb_availroom() helper instead. This also allows to get rid of
igmp_skb_size().
Reported-by: Wei Liu <[email protected]>
Fixes: 72e09ad107e7 ("ipv6: avoid high order allocations")
Signed-off-by: Daniel Borkmann <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Hannes Frederic Sowa <[email protected]>
Cc: David L Stevens <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/igmp.c | 11 +++++------
net/ipv6/mcast.c | 9 +++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 94d40cc79322..9c1979d85fc4 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -318,9 +318,7 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
return scount;
}
-#define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb))
-
-static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
+static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
{
struct sk_buff *skb;
struct rtable *rt;
@@ -330,6 +328,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
struct flowi4 fl4;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
+ unsigned int size = mtu;
while (1) {
skb = alloc_skb(size + hlen + tlen,
@@ -341,7 +340,6 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
return NULL;
}
skb->priority = TC_PRIO_CONTROL;
- igmp_skb_size(skb) = size;
rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0,
0, 0,
@@ -354,6 +352,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
skb_dst_set(skb, &rt->dst);
skb->dev = dev;
+ skb->reserved_tailroom = skb_end_offset(skb) -
+ min(mtu, skb_end_offset(skb));
skb_reserve(skb, hlen);
skb_reset_network_header(skb);
@@ -423,8 +423,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
return skb;
}
-#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \
- skb_tailroom(skb)) : 0)
+#define AVAILABLE(skb) ((skb) ? skb_availroom(skb) : 0)
static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
int type, int gdeleted, int sdeleted)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 452b6a1cc098..fce1cac483d0 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1522,7 +1522,7 @@ static void ip6_mc_hdr(struct sock *sk, struct sk_buff *skb,
hdr->daddr = *daddr;
}
-static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size)
+static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
{
struct net_device *dev = idev->dev;
struct net *net = dev_net(dev);
@@ -1533,13 +1533,13 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size)
const struct in6_addr *saddr;
int hlen = LL_RESERVED_SPACE(dev);
int tlen = dev->needed_tailroom;
+ unsigned int size = mtu + hlen + tlen;
int err;
u8 ra[8] = { IPPROTO_ICMPV6, 0,
IPV6_TLV_ROUTERALERT, 2, 0, 0,
IPV6_TLV_PADN, 0 };
/* we assume size > sizeof(ra) here */
- size += hlen + tlen;
/* limit our allocations to order-0 page */
size = min_t(int, size, SKB_MAX_ORDER(0, 0));
skb = sock_alloc_send_skb(sk, size, 1, &err);
@@ -1548,6 +1548,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, int size)
return NULL;
skb->priority = TC_PRIO_CONTROL;
+ skb->reserved_tailroom = skb_end_offset(skb) -
+ min(mtu, skb_end_offset(skb));
skb_reserve(skb, hlen);
if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
@@ -1661,8 +1663,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc,
return skb;
}
-#define AVAILABLE(skb) ((skb) ? ((skb)->dev ? (skb)->dev->mtu - (skb)->len : \
- skb_tailroom(skb)) : 0)
+#define AVAILABLE(skb) ((skb) ? skb_availroom(skb) : 0)
static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
int type, int gdeleted, int sdeleted)
--
2.8.1
From: Benjamin Poirier <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1837b2e2bcd23137766555a63867e649c0b637f0 upstream.
The current reserved_tailroom calculation fails to take hlen and tlen into
account.
skb:
[__hlen__|__data____________|__tlen___|__extra__]
^ ^
head skb_end_offset
In this representation, hlen + data + tlen is the size passed to alloc_skb.
"extra" is the extra space made available in __alloc_skb because of
rounding up by kmalloc. We can reorder the representation like so:
[__hlen__|__data____________|__extra__|__tlen___]
^ ^
head skb_end_offset
The maximum space available for ip headers and payload without
fragmentation is min(mtu, data + extra). Therefore,
reserved_tailroom
= data + extra + tlen - min(mtu, data + extra)
= skb_end_offset - hlen - min(mtu, skb_end_offset - hlen - tlen)
= skb_tailroom - min(mtu, skb_tailroom - tlen) ; after skb_reserve(hlen)
Compare the second line to the current expression:
reserved_tailroom = skb_end_offset - min(mtu, skb_end_offset)
and we can see that hlen and tlen are not taken into account.
The min() in the third line can be expanded into:
if mtu < skb_tailroom - tlen:
reserved_tailroom = skb_tailroom - mtu
else:
reserved_tailroom = tlen
Depending on hlen, tlen, mtu and the number of multicast address records,
the current code may output skbs that have less tailroom than
dev->needed_tailroom or it may output more skbs than needed because not all
space available is used.
Fixes: 4c672e4b ("ipv6: mld: fix add_grhead skb_over_panic for devs with large MTUs")
Signed-off-by: Benjamin Poirier <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Acked-by: Daniel Borkmann <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/skbuff.h | 24 ++++++++++++++++++++++++
net/ipv4/igmp.c | 3 +--
net/ipv6/mcast.c | 3 +--
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e492ab7aadbf..6242a9f80040 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1518,6 +1518,30 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
skb->tail += len;
}
+/**
+ * skb_tailroom_reserve - adjust reserved_tailroom
+ * @skb: buffer to alter
+ * @mtu: maximum amount of headlen permitted
+ * @needed_tailroom: minimum amount of reserved_tailroom
+ *
+ * Set reserved_tailroom so that headlen can be as large as possible but
+ * not larger than mtu and tailroom cannot be smaller than
+ * needed_tailroom.
+ * The required headroom should already have been reserved before using
+ * this function.
+ */
+static inline void skb_tailroom_reserve(struct sk_buff *skb, unsigned int mtu,
+ unsigned int needed_tailroom)
+{
+ SKB_LINEAR_ASSERT(skb);
+ if (mtu < skb_tailroom(skb) - needed_tailroom)
+ /* use at most mtu */
+ skb->reserved_tailroom = skb_tailroom(skb) - mtu;
+ else
+ /* use up to all available space */
+ skb->reserved_tailroom = needed_tailroom;
+}
+
static inline void skb_reset_inner_headers(struct sk_buff *skb)
{
skb->inner_mac_header = skb->mac_header;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 9c1979d85fc4..931bc8d6d8ee 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -352,9 +352,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
skb_dst_set(skb, &rt->dst);
skb->dev = dev;
- skb->reserved_tailroom = skb_end_offset(skb) -
- min(mtu, skb_end_offset(skb));
skb_reserve(skb, hlen);
+ skb_tailroom_reserve(skb, mtu, tlen);
skb_reset_network_header(skb);
pip = ip_hdr(skb);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index fce1cac483d0..df003455b2b5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1548,9 +1548,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
return NULL;
skb->priority = TC_PRIO_CONTROL;
- skb->reserved_tailroom = skb_end_offset(skb) -
- min(mtu, skb_end_offset(skb));
skb_reserve(skb, hlen);
+ skb_tailroom_reserve(skb, mtu, tlen);
if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
/* <draft-ietf-magma-mld-source-05.txt>:
--
2.8.1
From: Yuval Mintz <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 9c9a6524b5fdf6cb57c9ff627b7f242a6a4e0b00 upstream.
This adds support for 3 new PCI device combinations -
1077:16a1, 1077:16a4 and 1077:16ad.
Signed-off-by: Yuval Mintz <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 1e912b16c487..8600f7023831 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -261,11 +261,14 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = {
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_MF), BCM57810_MF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_O), BCM57840_O },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_4_10), BCM57840_4_10 },
+ { PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_NX2_57840_4_10), BCM57840_4_10 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_2_20), BCM57840_2_20 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57810_VF), BCM57810_VF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MFO), BCM57840_MFO },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_MF), BCM57840_MF },
+ { PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_NX2_57840_MF), BCM57840_MF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57840_VF), BCM57840_VF },
+ { PCI_VDEVICE(QLOGIC, PCI_DEVICE_ID_NX2_57840_VF), BCM57840_VF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811), BCM57811 },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811_MF), BCM57811_MF },
{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57811_VF), BCM57811_VF },
--
2.8.1
From: Ian Mitchell <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit c0365c0692d6ea038bb4feda308eec69e11292a3 upstream.
This patch allows the LPFC to start up without a fatal kernel bug based
on an exceeded KMALLOC_MAX_SIZE and a too large NR_CPU-based maskbits
field. The bug was based on the number of CPU cores in a system.
Using the get_cpu_mask() function declared in kernel/cpu.c allows the
driver to load on the community kernel 4.2 RC1.
Below is the kernel bug reproduced:
8<--------------------------------------------------------------------
2199382.828437 ( 0.005216)| lpfc 0003:02:00.0: enabling device (0140 -> 0142)
2199382.999272 ( 0.170835)| ------------[ cut here ]------------
2199382.999337 ( 0.000065)| WARNING: CPU: 84 PID: 404 at mm/slab_common.c:653 kmalloc_slab+0x2f/0x89()
2199383.004534 ( 0.005197)| Modules linked in: lpfc(+) usbcore(+) mptctl scsi_transport_fc sg lpc_ich i2c_i801 usb_common tpm_tis mfd_core tpm acpi_cpufreq button scsi_dh_alua scsi_dh_rdacusbcore: registered new device driver usb
2199383.020568 ( 0.016034)|
2199383.020581 ( 0.000013)| scsi_dh_hp_sw scsi_dh_emc scsi_dh gru thermal sata_nv processor piix fan thermal_sysehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
2199383.035288 ( 0.014707)|
2199383.035306 ( 0.000018)| hwmon ata_piix
2199383.035336 ( 0.000030)| CPU: 84 PID: 404 Comm: kworker/84:0 Not tainted 3.18.0-rc2-gat-00106-ga7ca10f-dirty #178
2199383.047077 ( 0.011741)| ehci-pci: EHCI PCI platform driver
2199383.047134 ( 0.000057)| Hardware name: SGI UV2000/ROMLEY, BIOS SGI UV 2000/3000 series BIOS 01/15/2013
2199383.056245 ( 0.009111)| Workqueue: events work_for_cpu_fn
2199383.066174 ( 0.009929)| 000000000000028d ffff88eef827bbe8 ffffffff815a542f 000000000000028d
2199383.069545 ( 0.003371)| ffffffff810ea142 ffff88eef827bc28 ffffffff8104365c ffff88eefe4006c8
2199383.076214 ( 0.006669)| 0000000000000000 00000000000080d0 0000000000000000 0000000000000004
2199383.079213 ( 0.002999)| Call Trace:
2199383.084084 ( 0.004871)| [<ffffffff815a542f>] dump_stack+0x49/0x62
2199383.087283 ( 0.003199)| [<ffffffff810ea142>] ? kmalloc_slab+0x2f/0x89
2199383.091415 ( 0.004132)| [<ffffffff8104365c>] warn_slowpath_common+0x77/0x92
2199383.095197 ( 0.003782)| [<ffffffff8104368c>] warn_slowpath_null+0x15/0x17
2199383.103336 ( 0.008139)| [<ffffffff810ea142>] kmalloc_slab+0x2f/0x89
2199383.107082 ( 0.003746)| [<ffffffff8110fd9e>] __kmalloc+0x13/0x16a
2199383.112531 ( 0.005449)| [<ffffffffa01a8ed9>] lpfc_pci_probe_one_s4+0x105b/0x1644 [lpfc]
2199383.115316 ( 0.002785)| [<ffffffff81302b92>] ? pci_bus_read_config_dword+0x75/0x87
2199383.123431 ( 0.008115)| [<ffffffffa01a951f>] lpfc_pci_probe_one+0x5d/0xcb5 [lpfc]
2199383.127364 ( 0.003933)| [<ffffffff81497119>] ? dbs_check_cpu+0x168/0x177
2199383.136438 ( 0.009074)| [<ffffffff81496fa5>] ? gov_queue_work+0xb4/0xc0
2199383.140407 ( 0.003969)| [<ffffffff8130b2a1>] local_pci_probe+0x1e/0x52
2199383.143105 ( 0.002698)| [<ffffffff81052c47>] work_for_cpu_fn+0x13/0x1b
2199383.147315 ( 0.004210)| [<ffffffff81054965>] process_one_work+0x222/0x35e
2199383.151379 ( 0.004064)| [<ffffffff81054e76>] worker_thread+0x3d5/0x46e
2199383.159402 ( 0.008023)| [<ffffffff81054aa1>] ? process_one_work+0x35e/0x35e
2199383.163097 ( 0.003695)| [<ffffffff810599c6>] kthread+0xc8/0xd2
2199383.167476 ( 0.004379)| [<ffffffff810598fe>] ? kthread_freezable_should_stop+0x5b/0x5b
2199383.176434 ( 0.008958)| [<ffffffff815a8cac>] ret_from_fork+0x7c/0xb0
2199383.180086 ( 0.003652)| [<ffffffff810598fe>] ? kthread_freezable_should_stop+0x5b/0x5b
2199383.192333 ( 0.012247)| ehci-pci 0000:00:1a.0: EHCI Host Controller
-------------------------------------------------------------------->8
The proposed solution was approved by James Smart at Emulex and tested
on a UV2 machine with 6144 cores. With the fix, the LPFC module loads
with no unwanted effects on the system.
Signed-off-by: Ian Mitchell <[email protected]>
Signed-off-by: Alex Thorlton <[email protected]>
Suggested-by: Robert Elliot <[email protected]>
[james.smart: resolve unused variable warning]
Signed-off-by: James Smart <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/lpfc/lpfc_init.c | 6 +-----
drivers/scsi/lpfc/lpfc_sli4.h | 1 -
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 647f5bfb3bd3..153de0cbfbc3 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -8395,7 +8395,6 @@ lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors)
#ifdef CONFIG_X86
struct cpuinfo_x86 *cpuinfo;
#endif
- struct cpumask *mask;
uint8_t chann[LPFC_FCP_IO_CHAN_MAX+1];
/* If there is no mapping, just return */
@@ -8489,11 +8488,8 @@ found:
first_cpu = cpu;
/* Now affinitize to the selected CPU */
- mask = &cpup->maskbits;
- cpumask_clear(mask);
- cpumask_set_cpu(cpu, mask);
i = irq_set_affinity_hint(phba->sli4_hba.msix_entries[idx].
- vector, mask);
+ vector, get_cpu_mask(cpu));
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"3330 Set Affinity: CPU %d channel %d "
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 85120b77aa0e..c29aa12cf408 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -447,7 +447,6 @@ struct lpfc_vector_map_info {
uint16_t core_id;
uint16_t irq;
uint16_t channel_id;
- struct cpumask maskbits;
};
#define LPFC_VECTOR_MAP_EMPTY 0xffff
--
2.8.1
From: Jeff Layton <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 5d05e54af3cdbb13cf19c557ff2184781b91a22c upstream.
Chuck pointed out a problem that crept in with commit 6ffa30d3f734 (nfs:
don't call blocking operations while !TASK_RUNNING). Linux counts tasks
in uninterruptible sleep against the load average, so this caused the
system's load average to be pinned at at least 1 when there was a
NFSv4.1+ mount active.
Not a huge problem, but it's probably worth fixing before we get too
many complaints about it. This patch converts the code back to use
TASK_INTERRUPTIBLE sleep, simply has it flush any signals on each loop
iteration. In practice no one should really be signalling this thread at
all, so I think this is reasonably safe.
With this change, there's also no need to game the hung task watchdog so
we can also convert the schedule_timeout call back to a normal schedule.
Reported-by: Chuck Lever <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Tested-by: Chuck Lever <[email protected]>
Fixes: commit 6ffa30d3f734 (“nfs: don't call blocking . . .”)
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/nfs/callback.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index f4cac2b06ac3..50443e6dc033 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -128,7 +128,7 @@ nfs41_callback_svc(void *vrqstp)
if (try_to_freeze())
continue;
- prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_UNINTERRUPTIBLE);
+ prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE);
spin_lock_bh(&serv->sv_cb_lock);
if (!list_empty(&serv->sv_cb_list)) {
req = list_first_entry(&serv->sv_cb_list,
@@ -142,10 +142,10 @@ nfs41_callback_svc(void *vrqstp)
error);
} else {
spin_unlock_bh(&serv->sv_cb_lock);
- /* schedule_timeout to game the hung task watchdog */
- schedule_timeout(60 * HZ);
+ schedule();
finish_wait(&serv->sv_cb_waitq, &wq);
}
+ flush_signals(current);
}
return 0;
}
--
2.8.1
3.12-stable review patch. If anyone has any objections, please let me know.
===============
In 3.12 commit e16f537864eb9cf68683d9e107706d1b31fcaa76 (net/ipv6: add
sysctl option accept_ra_min_hop_limit), upstream commit
8013d1d7eafb0589ca766db6b74026f76b7f5cb4, we added
DEVCONF_USE_OIF_ADDRS_ONLY and DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT
constants into <linux/ipv6.h>. But they have different values to
upstream because some values were added in upstream and we did not
backport them.
So we have:
DEVCONF_SUPPRESS_FRAG_NDISC,
+ DEVCONF_USE_OIF_ADDRS_ONLY,
+ DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
DEVCONF_MAX
And upstream has:
DEVCONF_SUPPRESS_FRAG_NDISC,
+ DEVCONF_ACCEPT_RA_FROM_LOCAL,
+ DEVCONF_USE_OPTIMISTIC,
+ DEVCONF_ACCEPT_RA_MTU,
+ DEVCONF_STABLE_SECRET,
+ DEVCONF_USE_OIF_ADDRS_ONLY,
+ DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
DEVCONF_MAX
Now, our DEVCONF_USE_OIF_ADDRS_ONLY corresponds to
DEVCONF_USE_OIF_ADDRS_ONLY-4 == DEVCONF_ACCEPT_RA_FROM_LOCAL from
upstream. Similarly the other constant.
Fix that by simply defining the missing constants to make the values
equal.
Signed-off-by: Jiri Slaby <[email protected]>
Reported-by: YOSHIFUJI Hideaki <[email protected]>
Cc: Luis Henriques <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: Hangbin Liu <[email protected]>
---
include/uapi/linux/ipv6.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 25955206757a..5985f28e98b3 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -163,6 +163,10 @@ enum {
DEVCONF_MLDV1_UNSOLICITED_REPORT_INTERVAL,
DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL,
DEVCONF_SUPPRESS_FRAG_NDISC,
+ DEVCONF_ACCEPT_RA_FROM_LOCAL,
+ DEVCONF_USE_OPTIMISTIC,
+ DEVCONF_ACCEPT_RA_MTU,
+ DEVCONF_STABLE_SECRET,
DEVCONF_USE_OIF_ADDRS_ONLY,
DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
DEVCONF_MAX
--
2.8.1
From: Wang Shilong <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit e84752d434b5cca0869e906e7b94d0531b25c6d3 upstream.
We won't change commit root, skip locking dance with commit root
when walking backrefs, this can speed up btrfs send operations.
Signed-off-by: Wang Shilong <[email protected]>
Signed-off-by: Josef Bacik <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/btrfs/backref.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 5859a05f3a76..b7f40f2630f4 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -842,8 +842,10 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
- if (!trans)
+ if (!trans) {
path->search_commit_root = 1;
+ path->skip_locking = 1;
+ }
/*
* grab both a lock on the path and a lock on the delayed ref head.
--
2.8.1
From: Markus Metzger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit a3ef2229c94ff70998724cb64b9cb4c77db9e950 upstream.
When using BTS on Core i7-4*, I get the below kernel warning.
$ perf record -c 1 -e branches:u ls
Message from syslogd@labpc1501 at Nov 11 15:49:25 ...
kernel:[ 438.317893] Uhhuh. NMI received for unknown reason 31 on CPU 2.
Message from syslogd@labpc1501 at Nov 11 15:49:25 ...
kernel:[ 438.317920] Do you have a strange power saving mode enabled?
Message from syslogd@labpc1501 at Nov 11 15:49:25 ...
kernel:[ 438.317945] Dazed and confused, but trying to continue
Make intel_pmu_handle_irq() take the full exit path when returning early.
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Markus Metzger <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Signed-off-by: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kernel/cpu/perf_event_intel.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index b400d0be5b03..d2080aa4322a 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1341,10 +1341,8 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
intel_pmu_disable_all();
handled = intel_pmu_drain_bts_buffer();
status = intel_pmu_get_status();
- if (!status) {
- intel_pmu_enable_all(0);
- return handled;
- }
+ if (!status)
+ goto done;
loops = 0;
again:
--
2.8.1
From: Roger Pau Monné <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 18779149101c0dd43ded43669ae2a92d21b6f9cb upstream.
Since indirect descriptors are in memory shared with the frontend, the
frontend could alter the first_sect and last_sect values after they have
been validated but before they are recorded in the request. This may
result in I/O requests that overflow the foreign page, possibly
overwriting local pages when the I/O request is executed.
When parsing indirect descriptors, only read first_sect and last_sect
once.
This is part of XSA155.
Signed-off-by: Roger Pau Monné <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Cc: Jan Beulich <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/block/xen-blkback/blkback.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index 6beaaf83680e..77128dea547f 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -853,6 +853,8 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
goto unmap;
for (n = 0, i = 0; n < nseg; n++) {
+ uint8_t first_sect, last_sect;
+
if ((n % SEGS_PER_INDIRECT_FRAME) == 0) {
/* Map indirect segments */
if (segments)
@@ -860,15 +862,18 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
segments = kmap_atomic(pages[n/SEGS_PER_INDIRECT_FRAME]->page);
}
i = n % SEGS_PER_INDIRECT_FRAME;
+
pending_req->segments[n]->gref = segments[i].gref;
- seg[n].nsec = segments[i].last_sect -
- segments[i].first_sect + 1;
- seg[n].offset = (segments[i].first_sect << 9);
- if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
- (segments[i].last_sect < segments[i].first_sect)) {
+
+ first_sect = READ_ONCE(segments[i].first_sect);
+ last_sect = READ_ONCE(segments[i].last_sect);
+ if (last_sect >= (PAGE_SIZE >> 9) || last_sect < first_sect) {
rc = -EINVAL;
goto unmap;
}
+
+ seg[n].nsec = last_sect - first_sect + 1;
+ seg[n].offset = first_sect << 9;
preq->nr_sects += seg[n].nsec;
}
--
2.8.1
From: Wei Huang <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit dc9b2d933a1d5782b70977024f862759c8ebb2f7 upstream.
Current KVM only supports RDMSR for K7_EVNTSEL0 and K7_PERFCTR0
MSRs. Reading the rest MSRs will trigger KVM to inject #GP into
guest VM. This causes a warning message "Failed to access perfctr
msr (MSR c0010001 is ffffffffffffffff)" on AMD host. This patch
adds RDMSR support for all K7_EVNTSELn and K7_PERFCTRn registers
and thus supresses the warning message.
Signed-off-by: Wei Huang <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/x86.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 356e78f2ad1a..c47a4ecb584c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2367,7 +2367,13 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_K7_HWCR:
case MSR_VM_HSAVE_PA:
case MSR_K7_EVNTSEL0:
+ case MSR_K7_EVNTSEL1:
+ case MSR_K7_EVNTSEL2:
+ case MSR_K7_EVNTSEL3:
case MSR_K7_PERFCTR0:
+ case MSR_K7_PERFCTR1:
+ case MSR_K7_PERFCTR2:
+ case MSR_K7_PERFCTR3:
case MSR_K8_INT_PENDING_MSG:
case MSR_AMD64_NB_CFG:
case MSR_FAM10H_MMIO_CONF_BASE:
--
2.8.1
From: Kirill Tkhai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit eeb61e53ea19be0c4015b00b2e8b3b2185436f2b upstream.
The race may happen when somebody is changing task_group of a forking task.
Child's cgroup is the same as parent's after dup_task_struct() (there just
memory copying). Also, cfs_rq and rt_rq are the same as parent's.
But if parent changes its task_group before it's called cgroup_post_fork(),
we do not reflect this situation on child. Child's cfs_rq and rt_rq remain
the same, while child's task_group changes in cgroup_post_fork().
To fix this we introduce fork() method, which calls sched_move_task() directly.
This function changes sched_task_group on appropriate (also its logic has
no problem with freshly created tasks, so we shouldn't introduce something
special; we are able just to use it).
Possibly, this decides the Burke Libbey's problem: https://lkml.org/lkml/2014/10/24/456
Signed-off-by: Kirill Tkhai <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Linus Torvalds <[email protected]>
Link: http://lkml.kernel.org/r/1414405105.19914.169.camel@tkhai
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/sched/core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3800316d7424..7381119ec1e9 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7233,6 +7233,11 @@ static void cpu_cgroup_css_offline(struct cgroup_subsys_state *css)
sched_offline_group(tg);
}
+static void cpu_cgroup_fork(struct task_struct *task)
+{
+ sched_move_task(task);
+}
+
static int cpu_cgroup_can_attach(struct cgroup_subsys_state *css,
struct cgroup_taskset *tset)
{
@@ -7602,6 +7607,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {
.css_free = cpu_cgroup_css_free,
.css_online = cpu_cgroup_css_online,
.css_offline = cpu_cgroup_css_offline,
+ .fork = cpu_cgroup_fork,
.can_attach = cpu_cgroup_can_attach,
.attach = cpu_cgroup_attach,
.exit = cpu_cgroup_exit,
--
2.8.1
From: John Allen <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit cb5490a5eea415106d7438df440da5fb1e17318d upstream.
Fix a bug where a kernel warning is triggered when performing a memory
hotplug on ppc64. This warning may also occur on any architecture that
uses the memory_probe_store interface.
WARNING: at drivers/base/memory.c:200
CPU: 9 PID: 13042 Comm: systemd-udevd Not tainted 4.4.0-rc4-00113-g0bd0f1e-dirty #7
NIP [c00000000055e034] pages_correctly_reserved+0x134/0x1b0
LR [c00000000055e7f8] memory_subsys_online+0x68/0x140
Call Trace:
memory_subsys_online+0x68/0x140
device_online+0xb4/0x120
store_mem_state+0xb0/0x180
dev_attr_store+0x34/0x60
sysfs_kf_write+0x64/0xa0
kernfs_fop_write+0x17c/0x1e0
__vfs_write+0x40/0x160
vfs_write+0xb8/0x200
SyS_write+0x60/0x110
system_call+0x38/0xd0
The warning is triggered because there is a udev rule that automatically
tries to online memory after it has been added. The udev rule varies
from distro to distro, but will generally look something like:
SUBSYSTEM=="memory", ACTION=="add", ATTR{state}=="offline", ATTR{state}="online"
On any architecture that uses memory_probe_store to reserve memory, the
udev rule will be triggered after the first section of the block is
reserved and will subsequently attempt to online the entire block,
interrupting the memory reservation process and causing the warning.
This patch modifies memory_probe_store to add a block of memory with a
single call to add_memory as opposed to looping through and adding each
section individually. A single call to add_memory is protected by the
mem_hotplug mutex which will prevent the udev rule from onlining memory
until the reservation of the entire block is complete.
Signed-off-by: John Allen <[email protected]>
Acked-by: Dave Hansen <[email protected]>
Cc: Nathan Fontenot <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/base/memory.c | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 3e2a3059b1f8..3c2b7174eb6f 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -417,8 +417,7 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
u64 phys_addr;
- int nid;
- int i, ret;
+ int nid, ret;
unsigned long pages_per_block = PAGES_PER_SECTION * sections_per_block;
phys_addr = simple_strtoull(buf, NULL, 0);
@@ -426,15 +425,12 @@ memory_probe_store(struct device *dev, struct device_attribute *attr,
if (phys_addr & ((pages_per_block << PAGE_SHIFT) - 1))
return -EINVAL;
- for (i = 0; i < sections_per_block; i++) {
- nid = memory_add_physaddr_to_nid(phys_addr);
- ret = add_memory(nid, phys_addr,
- PAGES_PER_SECTION << PAGE_SHIFT);
- if (ret)
- goto out;
+ nid = memory_add_physaddr_to_nid(phys_addr);
+ ret = add_memory(nid, phys_addr,
+ MIN_MEMORY_BLOCK_SIZE * sections_per_block);
- phys_addr += MIN_MEMORY_BLOCK_SIZE;
- }
+ if (ret)
+ goto out;
ret = count;
out:
--
2.8.1
From: Michal Hocko <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d8dc595ce3909fbc131bdf5ab8c9808fe624b18d upstream.
Eric has reported that he can see task(s) stuck in memcg OOM handler
regularly. The only way out is to
echo 0 > $GROUP/memory.oom_control
His usecase is:
- Setup a hierarchy with memory and the freezer (disable kernel oom and
have a process watch for oom).
- In that memory cgroup add a process with one thread per cpu.
- In one thread slowly allocate once per second I think it is 16M of ram
and mlock and dirty it (just to force the pages into ram and stay
there).
- When oom is achieved loop:
* attempt to freeze all of the tasks.
* if frozen send every task SIGKILL, unfreeze, remove the directory in
cgroupfs.
Eric has then pinpointed the issue to be memcg specific.
All tasks are sitting on the memcg_oom_waitq when memcg oom is disabled.
Those that have received fatal signal will bypass the charge and should
continue on their way out. The tricky part is that the exit path might
trigger a page fault (e.g. exit_robust_list), thus the memcg charge,
while its memcg is still under OOM because nobody has released any charges
yet.
Unlike with the in-kernel OOM handler the exiting task doesn't get
TIF_MEMDIE set so it doesn't shortcut further charges of the killed task
and falls to the memcg OOM again without any way out of it as there are no
fatal signals pending anymore.
This patch fixes the issue by checking PF_EXITING early in
mem_cgroup_try_charge and bypass the charge same as if it had fatal
signal pending or TIF_MEMDIE set.
Normally exiting tasks (aka not killed) will bypass the charge now but
this should be OK as the task is leaving and will release memory and
increasing the memory pressure just to release it in a moment seems
dubious wasting of cycles. Besides that charges after exit_signals should
be rare.
I am bringing this patch again (rebased on the current mmotm tree). I
hope we can move forward finally. If there is still an opposition then
I would really appreciate a concurrent approach so that we can discuss
alternatives.
http://comments.gmane.org/gmane.linux.kernel.stable/77650 is a reference
to the followup discussion when the patch has been dropped from the mmotm
last time.
Reported-by: Eric W. Biederman <[email protected]>
Signed-off-by: Michal Hocko <[email protected]>
Acked-by: David Rientjes <[email protected]>
Acked-by: Johannes Weiner <[email protected]>
Cc: KAMEZAWA Hiroyuki <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
mm/memcontrol.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 5904fc833523..4a1559d8739f 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2710,7 +2710,8 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
* MEMDIE process.
*/
if (unlikely(test_thread_flag(TIF_MEMDIE)
- || fatal_signal_pending(current)))
+ || fatal_signal_pending(current)
+ || current->flags & PF_EXITING))
goto bypass;
if (unlikely(task_in_memcg_oom(current)))
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 06ab30034ed9c200a570ab13c017bde248ddb2a6 upstream.
A kernel WARNING in snd_rawmidi_transmit_ack() is triggered by
syzkaller fuzzer:
WARNING: CPU: 1 PID: 20739 at sound/core/rawmidi.c:1136
Call Trace:
[< inline >] __dump_stack lib/dump_stack.c:15
[<ffffffff82999e2d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
[<ffffffff81352089>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
[<ffffffff813522b9>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
[<ffffffff84f80bd5>] snd_rawmidi_transmit_ack+0x275/0x400 sound/core/rawmidi.c:1136
[<ffffffff84fdb3c1>] snd_virmidi_output_trigger+0x4b1/0x5a0 sound/core/seq/seq_virmidi.c:163
[< inline >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
[<ffffffff84f87ed9>] snd_rawmidi_kernel_write1+0x549/0x780 sound/core/rawmidi.c:1223
[<ffffffff84f89fd3>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1273
[<ffffffff817b0323>] __vfs_write+0x113/0x480 fs/read_write.c:528
[<ffffffff817b1db7>] vfs_write+0x167/0x4a0 fs/read_write.c:577
[< inline >] SYSC_write fs/read_write.c:624
[<ffffffff817b50a1>] SyS_write+0x111/0x220 fs/read_write.c:616
[<ffffffff86336c36>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185
Also a similar warning is found but in another path:
Call Trace:
[< inline >] __dump_stack lib/dump_stack.c:15
[<ffffffff82be2c0d>] dump_stack+0x6f/0xa2 lib/dump_stack.c:50
[<ffffffff81355139>] warn_slowpath_common+0xd9/0x140 kernel/panic.c:482
[<ffffffff81355369>] warn_slowpath_null+0x29/0x30 kernel/panic.c:515
[<ffffffff8527e69a>] rawmidi_transmit_ack+0x24a/0x3b0 sound/core/rawmidi.c:1133
[<ffffffff8527e851>] snd_rawmidi_transmit_ack+0x51/0x80 sound/core/rawmidi.c:1163
[<ffffffff852d9046>] snd_virmidi_output_trigger+0x2b6/0x570 sound/core/seq/seq_virmidi.c:185
[< inline >] snd_rawmidi_output_trigger sound/core/rawmidi.c:150
[<ffffffff85285a0b>] snd_rawmidi_kernel_write1+0x4bb/0x760 sound/core/rawmidi.c:1252
[<ffffffff85287b73>] snd_rawmidi_write+0x543/0xb30 sound/core/rawmidi.c:1302
[<ffffffff817ba5f3>] __vfs_write+0x113/0x480 fs/read_write.c:528
[<ffffffff817bc087>] vfs_write+0x167/0x4a0 fs/read_write.c:577
[< inline >] SYSC_write fs/read_write.c:624
[<ffffffff817bf371>] SyS_write+0x111/0x220 fs/read_write.c:616
[<ffffffff86660276>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185
In the former case, the reason is that virmidi has an open code
calling snd_rawmidi_transmit_ack() with the value calculated outside
the spinlock. We may use snd_rawmidi_transmit() in a loop just for
consuming the input data, but even there, there is a race between
snd_rawmidi_transmit_peek() and snd_rawmidi_tranmit_ack().
Similarly in the latter case, it calls snd_rawmidi_transmit_peek() and
snd_rawmidi_tranmit_ack() separately without protection, so they are
racy as well.
The patch tries to address these issues by the following ways:
- Introduce the unlocked versions of snd_rawmidi_transmit_peek() and
snd_rawmidi_transmit_ack() to be called inside the explicit lock.
- Rewrite snd_rawmidi_transmit() to be race-free (the former case).
- Make the split calls (the latter case) protected in the rawmidi spin
lock.
Buglink: http://lkml.kernel.org/r/CACT4Y+YPq1+cYLkadwjWa5XjzF1_Vki1eHnVn-Lm0hzhSpu5PA@mail.gmail.com
Buglink: http://lkml.kernel.org/r/CACT4Y+acG4iyphdOZx47Nyq_VHGbpJQK-6xNpiqUjaZYqsXOGw@mail.gmail.com
Reported-by: Dmitry Vyukov <[email protected]>
Tested-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/sound/rawmidi.h | 4 ++
sound/core/rawmidi.c | 98 ++++++++++++++++++++++++++++++++------------
sound/core/seq/seq_virmidi.c | 17 +++++---
3 files changed, 88 insertions(+), 31 deletions(-)
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index adf0885153f3..f9d0133efaaa 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -167,6 +167,10 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+ unsigned char *buffer, int count);
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream,
+ int count);
/* main midi functions */
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 500765f20843..93bb23e058f9 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1049,23 +1049,16 @@ int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
}
/**
- * snd_rawmidi_transmit_peek - copy data from the internal buffer
+ * __snd_rawmidi_transmit_peek - copy data from the internal buffer
* @substream: the rawmidi substream
* @buffer: the buffer pointer
* @count: data size to transfer
*
- * Copies data from the internal output buffer to the given buffer.
- *
- * Call this in the interrupt handler when the midi output is ready,
- * and call snd_rawmidi_transmit_ack() after the transmission is
- * finished.
- *
- * Return: The size of copied data, or a negative error code on failure.
+ * This is a variant of snd_rawmidi_transmit_peek() without spinlock.
*/
-int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+int __snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
unsigned char *buffer, int count)
{
- unsigned long flags;
int result, count1;
struct snd_rawmidi_runtime *runtime = substream->runtime;
@@ -1074,7 +1067,6 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
return -EINVAL;
}
result = 0;
- spin_lock_irqsave(&runtime->lock, flags);
if (runtime->avail >= runtime->buffer_size) {
/* warning: lowlevel layer MUST trigger down the hardware */
goto __skip;
@@ -1099,31 +1091,51 @@ int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
}
}
__skip:
- spin_unlock_irqrestore(&runtime->lock, flags);
return result;
}
/**
- * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * snd_rawmidi_transmit_peek - copy data from the internal buffer
* @substream: the rawmidi substream
- * @count: the tranferred count
+ * @buffer: the buffer pointer
+ * @count: data size to transfer
*
- * Advances the hardware pointer for the internal output buffer with
- * the given size and updates the condition.
- * Call after the transmission is finished.
+ * Copies data from the internal output buffer to the given buffer.
*
- * Return: The advanced size if successful, or a negative error code on failure.
+ * Call this in the interrupt handler when the midi output is ready,
+ * and call snd_rawmidi_transmit_ack() after the transmission is
+ * finished.
+ *
+ * Return: The size of copied data, or a negative error code on failure.
*/
-int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+ unsigned char *buffer, int count)
{
+ struct snd_rawmidi_runtime *runtime = substream->runtime;
+ int result;
unsigned long flags;
+
+ spin_lock_irqsave(&runtime->lock, flags);
+ result = __snd_rawmidi_transmit_peek(substream, buffer, count);
+ spin_unlock_irqrestore(&runtime->lock, flags);
+ return result;
+}
+
+/**
+ * __snd_rawmidi_transmit_ack - acknowledge the transmission
+ * @substream: the rawmidi substream
+ * @count: the tranferred count
+ *
+ * This is a variant of __snd_rawmidi_transmit_ack() without spinlock.
+ */
+int __snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+{
struct snd_rawmidi_runtime *runtime = substream->runtime;
if (runtime->buffer == NULL) {
snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
return -EINVAL;
}
- spin_lock_irqsave(&runtime->lock, flags);
snd_BUG_ON(runtime->avail + count > runtime->buffer_size);
runtime->hw_ptr += count;
runtime->hw_ptr %= runtime->buffer_size;
@@ -1133,11 +1145,33 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
if (runtime->drain || snd_rawmidi_ready(substream))
wake_up(&runtime->sleep);
}
- spin_unlock_irqrestore(&runtime->lock, flags);
return count;
}
/**
+ * snd_rawmidi_transmit_ack - acknowledge the transmission
+ * @substream: the rawmidi substream
+ * @count: the transferred count
+ *
+ * Advances the hardware pointer for the internal output buffer with
+ * the given size and updates the condition.
+ * Call after the transmission is finished.
+ *
+ * Return: The advanced size if successful, or a negative error code on failure.
+ */
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
+{
+ struct snd_rawmidi_runtime *runtime = substream->runtime;
+ int result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&runtime->lock, flags);
+ result = __snd_rawmidi_transmit_ack(substream, count);
+ spin_unlock_irqrestore(&runtime->lock, flags);
+ return result;
+}
+
+/**
* snd_rawmidi_transmit - copy from the buffer to the device
* @substream: the rawmidi substream
* @buffer: the buffer pointer
@@ -1150,12 +1184,22 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
unsigned char *buffer, int count)
{
+ struct snd_rawmidi_runtime *runtime = substream->runtime;
+ int result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&runtime->lock, flags);
if (!substream->opened)
- return -EBADFD;
- count = snd_rawmidi_transmit_peek(substream, buffer, count);
- if (count < 0)
- return count;
- return snd_rawmidi_transmit_ack(substream, count);
+ result = -EBADFD;
+ else {
+ count = __snd_rawmidi_transmit_peek(substream, buffer, count);
+ if (count <= 0)
+ result = count;
+ else
+ result = __snd_rawmidi_transmit_ack(substream, count);
+ }
+ spin_unlock_irqrestore(&runtime->lock, flags);
+ return result;
}
static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
@@ -1734,3 +1778,5 @@ EXPORT_SYMBOL(snd_rawmidi_kernel_open);
EXPORT_SYMBOL(snd_rawmidi_kernel_release);
EXPORT_SYMBOL(snd_rawmidi_kernel_read);
EXPORT_SYMBOL(snd_rawmidi_kernel_write);
+EXPORT_SYMBOL(__snd_rawmidi_transmit_peek);
+EXPORT_SYMBOL(__snd_rawmidi_transmit_ack);
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index 0fa691e01384..6b38e7c2641a 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -155,21 +155,26 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
struct snd_virmidi *vmidi = substream->runtime->private_data;
int count, res;
unsigned char buf[32], *pbuf;
+ unsigned long flags;
if (up) {
vmidi->trigger = 1;
if (vmidi->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH &&
!(vmidi->rdev->flags & SNDRV_VIRMIDI_SUBSCRIBE)) {
- snd_rawmidi_transmit_ack(substream, substream->runtime->buffer_size - substream->runtime->avail);
- return; /* ignored */
+ while (snd_rawmidi_transmit(substream, buf,
+ sizeof(buf)) > 0) {
+ /* ignored */
+ }
+ return;
}
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
return;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}
+ spin_lock_irqsave(&substream->runtime->lock, flags);
while (1) {
- count = snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
+ count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
if (count <= 0)
break;
pbuf = buf;
@@ -179,16 +184,18 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
snd_midi_event_reset_encode(vmidi->parser);
continue;
}
- snd_rawmidi_transmit_ack(substream, res);
+ __snd_rawmidi_transmit_ack(substream, res);
pbuf += res;
count -= res;
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
- return;
+ goto out;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}
}
}
+ out:
+ spin_unlock_irqrestore(&substream->runtime->lock, flags);
} else {
vmidi->trigger = 0;
}
--
2.8.1
From: Gabriel Krisman Bertazi <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 21b81716c6bff24cda52dc75588455f879ddbfe9 upstream.
Commit d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite") removed
the end of line handling when storing the update_fw sysfs attribute.
This changed the userpace API because it started refusing writes
terminated by a line feed, which broke the update tools we already have.
This patch re-adds that handling, so both a write terminated by a line
feed or not can make it through with the update.
Fixes: d63c7dd5bcb9 ("ipr: Fix out-of-bounds null overwrite")
Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
Cc: Insu Yun <[email protected]>
Acked-by: Brian King <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Cc: Ben Hutchings <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/ipr.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 4fa12a4467d2..d4473d2f8739 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3946,6 +3946,7 @@ static ssize_t ipr_store_update_fw(struct device *dev,
struct ipr_sglist *sglist;
char fname[100];
char *src;
+ char *endline;
int result, dnld_size;
if (!capable(CAP_SYS_ADMIN))
@@ -3953,6 +3954,10 @@ static ssize_t ipr_store_update_fw(struct device *dev,
snprintf(fname, sizeof(fname), "%s", buf);
+ endline = strchr(fname, '\n');
+ if (endline)
+ *endline = '\0';
+
if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
return -EIO;
--
2.8.1
From: Takashi Iwai <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d99a36f4728fcbcc501b78447f625bdcce15b842 upstream.
When multiple concurrent writes happen on the ALSA sequencer device
right after the open, it may try to allocate vmalloc buffer for each
write and leak some of them. It's because the presence check and the
assignment of the buffer is done outside the spinlock for the pool.
The fix is to move the check and the assignment into the spinlock.
(The current implementation is suboptimal, as there can be multiple
unnecessary vmallocs because the allocation is done before the check
in the spinlock. But the pool size is already checked beforehand, so
this isn't a big problem; that is, the only possible path is the
multiple writes before any pool assignment, and practically seen, the
current coverage should be "good enough".)
The issue was triggered by syzkaller fuzzer.
Buglink: http://lkml.kernel.org/r/CACT4Y+bSzazpXNvtAr=WXaL8hptqjHwqEyFA+VN2AWEx=aurkg@mail.gmail.com
Reported-by: Dmitry Vyukov <[email protected]>
Tested-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/core/seq/seq_memory.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index f478f770bf52..652350e2533f 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -383,17 +383,20 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
if (snd_BUG_ON(!pool))
return -EINVAL;
- if (pool->ptr) /* should be atomic? */
- return 0;
- pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
- if (pool->ptr == NULL) {
- snd_printd("seq: malloc for sequencer events failed\n");
+ cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
+ if (!cellptr)
return -ENOMEM;
- }
/* add new cells to the free cell list */
spin_lock_irqsave(&pool->lock, flags);
+ if (pool->ptr) {
+ spin_unlock_irqrestore(&pool->lock, flags);
+ vfree(cellptr);
+ return 0;
+ }
+
+ pool->ptr = cellptr;
pool->free = NULL;
for (cell = 0; cell < pool->size; cell++) {
--
2.8.1
From: David Vrabel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 454d5d882c7e412b840e3c99010fe81a9862f6fb upstream.
Using RING_GET_REQUEST() on a shared ring is easy to use incorrectly
(i.e., by not considering that the other end may alter the data in the
shared ring while it is being inspected). Safe usage of a request
generally requires taking a local copy.
Provide a RING_COPY_REQUEST() macro to use instead of
RING_GET_REQUEST() and an open-coded memcpy(). This takes care of
ensuring that the copy is done correctly regardless of any possible
compiler optimizations.
Use a volatile source to prevent the compiler from reordering or
omitting the copy.
This is part of XSA155.
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/xen/interface/io/ring.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index 7d28aff605c7..7dc685b4057d 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -181,6 +181,20 @@ struct __name##_back_ring { \
#define RING_GET_REQUEST(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do { \
+ /* Use volatile to force the copy into _req. */ \
+ *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
+} while (0)
+
#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
--
2.8.1
From: David Vrabel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 0f589967a73f1f30ab4ac4dd9ce0bb399b4d6357 upstream.
The last from guest transmitted request gives no indication about the
minimum amount of credit that the guest might need to send a packet
since the last packet might have been a small one.
Instead allow for the worst case 128 KiB packet.
This is part of XSA155.
Reviewed-by: Wei Liu <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/xen-netback/netback.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index a1186533cee8..d4a1db9fb224 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -695,9 +695,7 @@ static void tx_add_credit(struct xenvif *vif)
* Allow a burst big enough to transmit a jumbo packet of up to 128kB.
* Otherwise the interface can seize up due to insufficient credit.
*/
- max_burst = RING_GET_REQUEST(&vif->tx, vif->tx.req_cons)->size;
- max_burst = min(max_burst, 131072UL);
- max_burst = max(max_burst, vif->credit_bytes);
+ max_burst = max(131072UL, vif->credit_bytes);
/* Take care that adding a new chunk of credit doesn't wrap to zero. */
max_credit = vif->remaining_credit + vif->credit_bytes;
--
2.8.1
From: David Vrabel <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 68a33bfd8403e4e22847165d149823a2e0e67c9c upstream.
Instead of open-coding memcpy()s and directly accessing Tx and Rx
requests, use the new RING_COPY_REQUEST() that ensures the local copy
is correct.
This is more than is strictly necessary for guest Rx requests since
only the id and gref fields are used and it is harmless if the
frontend modifies these.
This is part of XSA155.
Reviewed-by: Wei Liu <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/xen-netback/netback.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index d4a1db9fb224..a773794bb7f2 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -313,17 +313,17 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif *vif,
struct netrx_pending_operations *npo)
{
struct xenvif_rx_meta *meta;
- struct xen_netif_rx_request *req;
+ struct xen_netif_rx_request req;
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
meta->gso_size = 0;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
npo->copy_off = 0;
- npo->copy_gref = req->gref;
+ npo->copy_gref = req.gref;
return meta;
}
@@ -424,7 +424,7 @@ static int xenvif_gop_skb(struct sk_buff *skb,
struct xenvif *vif = netdev_priv(skb->dev);
int nr_frags = skb_shinfo(skb)->nr_frags;
int i;
- struct xen_netif_rx_request *req;
+ struct xen_netif_rx_request req;
struct xenvif_rx_meta *meta;
unsigned char *data;
int head = 1;
@@ -434,14 +434,14 @@ static int xenvif_gop_skb(struct sk_buff *skb,
/* Set up a GSO prefix descriptor, if necessary */
if (skb_shinfo(skb)->gso_size && vif->gso_prefix) {
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
meta->gso_size = skb_shinfo(skb)->gso_size;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
}
- req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++);
+ RING_COPY_REQUEST(&vif->rx, vif->rx.req_cons++, &req);
meta = npo->meta + npo->meta_prod++;
if (!vif->gso_prefix)
@@ -450,9 +450,9 @@ static int xenvif_gop_skb(struct sk_buff *skb,
meta->gso_size = 0;
meta->size = 0;
- meta->id = req->id;
+ meta->id = req.id;
npo->copy_off = 0;
- npo->copy_gref = req->gref;
+ npo->copy_gref = req.gref;
data = skb->data;
while (data < skb_tail_pointer(skb)) {
@@ -721,7 +721,7 @@ static void xenvif_tx_err(struct xenvif *vif,
make_tx_response(vif, txp, XEN_NETIF_RSP_ERROR);
if (cons == end)
break;
- txp = RING_GET_REQUEST(&vif->tx, cons++);
+ RING_COPY_REQUEST(&vif->tx, cons++, txp);
} while (1);
vif->tx.req_cons = cons;
}
@@ -786,8 +786,7 @@ static int xenvif_count_requests(struct xenvif *vif,
if (drop_err)
txp = &dropped_tx;
- memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + slots),
- sizeof(*txp));
+ RING_COPY_REQUEST(&vif->tx, cons + slots, txp);
/* If the guest submitted a frame >= 64 KiB then
* first->size overflowed and following slots will
@@ -1073,8 +1072,7 @@ static int xenvif_get_extras(struct xenvif *vif,
return -EBADR;
}
- memcpy(&extra, RING_GET_REQUEST(&vif->tx, cons),
- sizeof(extra));
+ RING_COPY_REQUEST(&vif->tx, cons, &extra);
if (unlikely(!extra.type ||
extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
vif->tx.req_cons = ++cons;
@@ -1250,7 +1248,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif)
idx = vif->tx.req_cons;
rmb(); /* Ensure that we see the request before we copy it. */
- memcpy(&txreq, RING_GET_REQUEST(&vif->tx, idx), sizeof(txreq));
+ RING_COPY_REQUEST(&vif->tx, idx, &txreq);
/* Credit-based scheduling. */
if (txreq.size > vif->remaining_credit &&
--
2.8.1
From: Roger Pau Monné <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 1f13d75ccb806260079e0679d55d9253e370ec8a upstream.
A compiler may load a switch statement value multiple times, which could
be bad when the value is in memory shared with the frontend.
When converting a non-native request to a native one, ensure that
src->operation is only loaded once by using READ_ONCE().
This is part of XSA155.
Signed-off-by: Roger Pau Monné <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Konrad Rzeszutek Wilk <[email protected]>
Cc: "Jan Beulich" <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/block/xen-blkback/common.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 8d8807563d99..ab225ff1af8e 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -388,8 +388,8 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
struct blkif_x86_32_request *src)
{
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
- dst->operation = src->operation;
- switch (src->operation) {
+ dst->operation = READ_ONCE(src->operation);
+ switch (dst->operation) {
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER:
@@ -436,8 +436,8 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
struct blkif_x86_64_request *src)
{
int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST, j;
- dst->operation = src->operation;
- switch (src->operation) {
+ dst->operation = READ_ONCE(src->operation);
+ switch (dst->operation) {
case BLKIF_OP_READ:
case BLKIF_OP_WRITE:
case BLKIF_OP_WRITE_BARRIER:
--
2.8.1
From: Insu Yun <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit d63c7dd5bcb9441af0526d370c43a65ca2c980d9 upstream.
Return value of snprintf is not bound by size value, 2nd argument.
(https://www.kernel.org/doc/htmldocs/kernel-api/API-snprintf.html).
Return value is number of printed chars, can be larger than 2nd
argument. Therefore, it can write null byte out of bounds ofbuffer.
Since snprintf puts null, it does not need to put additional null byte.
Signed-off-by: Insu Yun <[email protected]>
Reviewed-by: Shane Seymour <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Cc: Ben Hutchings <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/scsi/ipr.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 0f6412db121c..4fa12a4467d2 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3946,13 +3946,12 @@ static ssize_t ipr_store_update_fw(struct device *dev,
struct ipr_sglist *sglist;
char fname[100];
char *src;
- int len, result, dnld_size;
+ int result, dnld_size;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- len = snprintf(fname, 99, "%s", buf);
- fname[len-1] = '\0';
+ snprintf(fname, sizeof(fname), "%s", buf);
if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
--
2.8.1
From: "Eric W. Biederman" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit da362b09e42ee0bcaf0356afee6078b4f324baff upstream.
Andrew Vagin <[email protected]> writes:
> #define _GNU_SOURCE
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <sched.h>
> #include <unistd.h>
> #include <sys/mount.h>
>
> int main(int argc, char **argv)
> {
> int fd;
>
> fd = open("/proc/self/ns/mnt", O_RDONLY);
> if (fd < 0)
> return 1;
> while (1) {
> if (umount2("/", MNT_DETACH) ||
> setns(fd, CLONE_NEWNS))
> break;
> }
>
> return 0;
> }
>
> root@ubuntu:/home/avagin# gcc -Wall nsenter.c -o nsenter
> root@ubuntu:/home/avagin# strace ./nsenter
> execve("./nsenter", ["./nsenter"], [/* 22 vars */]) = 0
> ...
> open("/proc/self/ns/mnt", O_RDONLY) = 3
> umount("/", MNT_DETACH) = 0
> setns(3, 131072) = 0
> umount("/", MNT_DETACH
>
causes:
> [ 260.548301] ------------[ cut here ]------------
> [ 260.550941] kernel BUG at /build/buildd/linux-3.13.0/fs/pnode.c:372!
> [ 260.552068] invalid opcode: 0000 [#1] SMP
> [ 260.552068] Modules linked in: xt_CHECKSUM iptable_mangle xt_tcpudp xt_addrtype xt_conntrack ipt_MASQUERADE iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack bridge stp llc dm_thin_pool dm_persistent_data dm_bufio dm_bio_prison iptable_filter ip_tables x_tables crct10dif_pclmul crc32_pclmul ghash_clmulni_intel binfmt_misc nfsd auth_rpcgss nfs_acl aesni_intel nfs lockd aes_x86_64 sunrpc fscache lrw gf128mul glue_helper ablk_helper cryptd serio_raw ppdev parport_pc lp parport btrfs xor raid6_pq libcrc32c psmouse floppy
> [ 260.552068] CPU: 0 PID: 1723 Comm: nsenter Not tainted 3.13.0-30-generic #55-Ubuntu
> [ 260.552068] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
> [ 260.552068] task: ffff8800376097f0 ti: ffff880074824000 task.ti: ffff880074824000
> [ 260.552068] RIP: 0010:[<ffffffff811e9483>] [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [ 260.552068] RSP: 0018:ffff880074825e98 EFLAGS: 00010246
> [ 260.552068] RAX: ffff88007c741140 RBX: 0000000000000002 RCX: ffff88007c741190
> [ 260.552068] RDX: ffff88007c741190 RSI: ffff880074825ec0 RDI: ffff880074825ec0
> [ 260.552068] RBP: ffff880074825eb0 R08: 00000000000172e0 R09: ffff88007fc172e0
> [ 260.552068] R10: ffffffff811cc642 R11: ffffea0001d59000 R12: ffff88007c741140
> [ 260.552068] R13: ffff88007c741140 R14: ffff88007c741140 R15: 0000000000000000
> [ 260.552068] FS: 00007fd5c7e41740(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
> [ 260.552068] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 260.552068] CR2: 00007fd5c7968050 CR3: 0000000070124000 CR4: 00000000000406f0
> [ 260.552068] Stack:
> [ 260.552068] 0000000000000002 0000000000000002 ffff88007c631000 ffff880074825ed8
> [ 260.552068] ffffffff811dcfac ffff88007c741140 0000000000000002 ffff88007c741160
> [ 260.552068] ffff880074825f38 ffffffff811dd12b ffffffff811cc642 0000000075640000
> [ 260.552068] Call Trace:
> [ 260.552068] [<ffffffff811dcfac>] umount_tree+0x20c/0x260
> [ 260.552068] [<ffffffff811dd12b>] do_umount+0x12b/0x300
> [ 260.552068] [<ffffffff811cc642>] ? final_putname+0x22/0x50
> [ 260.552068] [<ffffffff811cc849>] ? putname+0x29/0x40
> [ 260.552068] [<ffffffff811dd88c>] SyS_umount+0xdc/0x100
> [ 260.552068] [<ffffffff8172aeff>] tracesys+0xe1/0xe6
> [ 260.552068] Code: 89 50 08 48 8b 50 08 48 89 02 49 89 45 08 e9 72 ff ff ff 0f 1f 44 00 00 4c 89 e6 4c 89 e7 e8 f5 f6 ff ff 48 89 c3 e9 39 ff ff ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 90 66 66 66 66 90 55 b8 01
> [ 260.552068] RIP [<ffffffff811e9483>] propagate_umount+0x123/0x130
> [ 260.552068] RSP <ffff880074825e98>
> [ 260.611451] ---[ end trace 11c33d85f1d4c652 ]--
Which in practice is totally uninteresting. Only the global root user can
do it, and it is just a stupid thing to do.
However that is no excuse to allow a silly way to oops the kernel.
We can avoid this silly problem by setting MNT_LOCKED on the rootfs
mount point and thus avoid needing any special cases in the unmount
code.
Signed-off-by: "Eric W. Biederman" <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/namespace.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/namespace.c b/fs/namespace.c
index bdc6223a7500..d727b0ce11df 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2809,6 +2809,7 @@ static void __init init_mount_tree(void)
root.mnt = mnt;
root.dentry = mnt->mnt_root;
+ mnt->mnt_flags |= MNT_LOCKED;
set_fs_pwd(current->fs, &root);
set_fs_root(current->fs, &root);
--
2.8.1
From: Christian Borntraeger <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit 230fa253df6352af12ad0a16128760b5cb3f92df upstream.
ACCESS_ONCE does not work reliably on non-scalar types. For
example gcc 4.6 and 4.7 might remove the volatile tag for such
accesses during the SRA (scalar replacement of aggregates) step
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145)
Let's provide READ_ONCE/ASSIGN_ONCE that will do all accesses via
scalar types as suggested by Linus Torvalds. Accesses larger than
the machines word size cannot be guaranteed to be atomic. These
macros will use memcpy and emit a build warning.
Signed-off-by: Christian Borntraeger <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
include/linux/compiler.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 19a199414bd0..237063adbe1b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -179,6 +179,80 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
#endif
+#include <uapi/linux/types.h>
+
+static __always_inline void data_access_exceeds_word_size(void)
+#ifdef __compiletime_warning
+__compiletime_warning("data access exceeds word size and won't be atomic")
+#endif
+;
+
+static __always_inline void data_access_exceeds_word_size(void)
+{
+}
+
+static __always_inline void __read_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
+ case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
+ case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
+#ifdef CONFIG_64BIT
+ case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)res, (const void *)p, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+static __always_inline void __assign_once_size(volatile void *p, void *res, int size)
+{
+ switch (size) {
+ case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
+ case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
+ case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
+#ifdef CONFIG_64BIT
+ case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
+#endif
+ default:
+ barrier();
+ __builtin_memcpy((void *)p, (const void *)res, size);
+ data_access_exceeds_word_size();
+ barrier();
+ }
+}
+
+/*
+ * Prevent the compiler from merging or refetching reads or writes. The
+ * compiler is also forbidden from reordering successive instances of
+ * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the
+ * compiler is aware of some particular ordering. One way to make the
+ * compiler aware of ordering is to put the two invocations of READ_ONCE,
+ * ASSIGN_ONCE or ACCESS_ONCE() in different C statements.
+ *
+ * In contrast to ACCESS_ONCE these two macros will also work on aggregate
+ * data types like structs or unions. If the size of the accessed data
+ * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
+ * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a
+ * compile-time warning.
+ *
+ * Their two major use cases are: (1) Mediating communication between
+ * process-level code and irq/NMI handlers, all running on the same CPU,
+ * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
+ * mutilate accesses that either do not require ordering or that interact
+ * with an explicit memory barrier or atomic instruction that provides the
+ * required ordering.
+ */
+
+#define READ_ONCE(x) \
+ ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })
+
+#define ASSIGN_ONCE(val, x) \
+ ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; })
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
--
2.8.1
From: "David S. Miller" <[email protected]>
3.12-stable review patch. If anyone has any objections, please let me know.
===============
commit fbd40ea0180a2d328c5adc61414dc8bab9335ce2 upstream.
When an inetdev is destroyed, every address assigned to the interface
is removed. And in this scenerio we do two pointless things which can
be very expensive if the number of assigned interfaces is large:
1) Address promotion. We are deleting all addresses, so there is no
point in doing this.
2) A full nf conntrack table purge for every address. We only need to
do this once, as is already caught by the existing
masq_dev_notifier so masq_inet_event() can skip this.
[mk] 3.12.*: The change in masq_inet_event() needs to be duplicated in
both IPv4 and IPv6 version of the function, these two were merged in
3.18.
Reported-by: Solar Designer <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Tested-by: Cyrill Gorcunov <[email protected]>
Acked-by: Michal Kubecek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/devinet.c | 4 ++++
net/ipv4/fib_frontend.c | 4 ++++
net/ipv4/netfilter/ipt_MASQUERADE.c | 12 ++++++++++--
net/ipv6/netfilter/ip6t_MASQUERADE.c | 12 ++++++++++--
4 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 68447109000f..6678bebb82c8 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -328,6 +328,9 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
ASSERT_RTNL();
+ if (in_dev->dead)
+ goto no_promotions;
+
/* 1. Deleting primary ifaddr forces deletion all secondaries
* unless alias promotion is set
**/
@@ -374,6 +377,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
fib_del_ifaddr(ifa, ifa1);
}
+no_promotions:
/* 2. Unlink it */
*ifap = ifa1->ifa_next;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f7f8cff67344..25a0946f7074 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -812,6 +812,9 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
subnet = 1;
}
+ if (in_dev->dead)
+ goto no_promotions;
+
/* Deletion is more complicated than add.
* We should take care of not to delete too much :-)
*
@@ -887,6 +890,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
}
}
+no_promotions:
if (!(ok & BRD_OK))
fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
if (subnet && ifa->ifa_prefixlen < 31) {
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 00352ce0f0de..3bc1c98aa2f0 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -128,10 +128,18 @@ static int masq_inet_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
- struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev;
+ struct in_device *idev = ((struct in_ifaddr *)ptr)->ifa_dev;
struct netdev_notifier_info info;
- netdev_notifier_info_init(&info, dev);
+ /* The masq_dev_notifier will catch the case of the device going
+ * down. So if the inetdev is dead and being destroyed we have
+ * no work to do. Otherwise this is an individual address removal
+ * and we have to perform the flush.
+ */
+ if (idev->dead)
+ return NOTIFY_DONE;
+
+ netdev_notifier_info_init(&info, idev->dev);
return masq_device_event(this, event, &info);
}
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
index 3e4e92d5e157..bee09e9050c3 100644
--- a/net/ipv6/netfilter/ip6t_MASQUERADE.c
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -88,10 +88,18 @@ static struct notifier_block masq_dev_notifier = {
static int masq_inet_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
- struct inet6_ifaddr *ifa = ptr;
+ struct inet6_dev *idev = ((struct inet6_ifaddr *)ptr)->idev;
struct netdev_notifier_info info;
- netdev_notifier_info_init(&info, ifa->idev->dev);
+ /* The masq_dev_notifier will catch the case of the device going
+ * down. So if the inetdev is dead and being destroyed we have
+ * no work to do. Otherwise this is an individual address removal
+ * and we have to perform the flush.
+ */
+ if (idev->dead)
+ return NOTIFY_DONE;
+
+ netdev_notifier_info_init(&info, idev->dev);
return masq_device_event(this, event, &info);
}
--
2.8.1
On 04/11/2016 03:22 PM, Jiri Slaby wrote:
> From: Christian Borntraeger <[email protected]>
>
> 3.12-stable review patch. If anyone has any objections, please let me know.
>
As I wrote you 2 weeks ago, there are several patches on top, which are necessary to not
break compile on some architectures or to get the final names.
Please do not apply this stand-alone.
> ===============
>
> commit 230fa253df6352af12ad0a16128760b5cb3f92df upstream.
>
> ACCESS_ONCE does not work reliably on non-scalar types. For
> example gcc 4.6 and 4.7 might remove the volatile tag for such
> accesses during the SRA (scalar replacement of aggregates) step
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145)
>
> Let's provide READ_ONCE/ASSIGN_ONCE that will do all accesses via
> scalar types as suggested by Linus Torvalds. Accesses larger than
> the machines word size cannot be guaranteed to be atomic. These
> macros will use memcpy and emit a build warning.
>
> Signed-off-by: Christian Borntraeger <[email protected]>
> Signed-off-by: Jiri Slaby <[email protected]>
> ---
> include/linux/compiler.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 74 insertions(+)
>
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 19a199414bd0..237063adbe1b 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -179,6 +179,80 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
> # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
> #endif
>
> +#include <uapi/linux/types.h>
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +#ifdef __compiletime_warning
> +__compiletime_warning("data access exceeds word size and won't be atomic")
> +#endif
> +;
> +
> +static __always_inline void data_access_exceeds_word_size(void)
> +{
> +}
> +
> +static __always_inline void __read_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(__u8 *)res = *(volatile __u8 *)p; break;
> + case 2: *(__u16 *)res = *(volatile __u16 *)p; break;
> + case 4: *(__u32 *)res = *(volatile __u32 *)p; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(__u64 *)res = *(volatile __u64 *)p; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)res, (const void *)p, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +static __always_inline void __assign_once_size(volatile void *p, void *res, int size)
> +{
> + switch (size) {
> + case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
> + case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
> + case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
> +#ifdef CONFIG_64BIT
> + case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
> +#endif
> + default:
> + barrier();
> + __builtin_memcpy((void *)p, (const void *)res, size);
> + data_access_exceeds_word_size();
> + barrier();
> + }
> +}
> +
> +/*
> + * Prevent the compiler from merging or refetching reads or writes. The
> + * compiler is also forbidden from reordering successive instances of
> + * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the
> + * compiler is aware of some particular ordering. One way to make the
> + * compiler aware of ordering is to put the two invocations of READ_ONCE,
> + * ASSIGN_ONCE or ACCESS_ONCE() in different C statements.
> + *
> + * In contrast to ACCESS_ONCE these two macros will also work on aggregate
> + * data types like structs or unions. If the size of the accessed data
> + * type exceeds the word size of the machine (e.g., 32 bits or 64 bits)
> + * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a
> + * compile-time warning.
> + *
> + * Their two major use cases are: (1) Mediating communication between
> + * process-level code and irq/NMI handlers, all running on the same CPU,
> + * and (2) Ensuring that the compiler does not fold, spindle, or otherwise
> + * mutilate accesses that either do not require ordering or that interact
> + * with an explicit memory barrier or atomic instruction that provides the
> + * required ordering.
> + */
> +
> +#define READ_ONCE(x) \
> + ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> +#define ASSIGN_ONCE(val, x) \
> + ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; })
> +
> #endif /* __KERNEL__ */
>
> #endif /* __ASSEMBLY__ */
>
On 04/11/2016 07:23 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.58 release.
> There are 98 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 Wed Apr 13 15:21:57 CEST 2016.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.58-rc1.xz
> and the diffstat can be found below.
>
> thanks,
> js
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
On 04/11/2016, 03:37 PM, Guenter Roeck wrote:
> On 04/11/2016 06:23 AM, Jiri Slaby wrote:
>> This is the start of the stable review cycle for the 3.12.58 release.
>> There are 98 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 Wed Apr 13 15:21:57 CEST 2016.
>> Anything received after that time might be too late.
>>
>
> Build results:
> total: 125 pass: 125 fail: 0
> Qemu test results:
> total: 84 pass: 84 fail: 0
>
> Details are available at http://kerneltests.org/builders.
On 04/11/2016, 07:28 PM, shuahkh wrote:
> Compiled and booted on my test system. No dmesg regressions.
Thank you both!
--
js
suse labs