Linux 3.2.93

From: Ben Hutchings
Date: Fri Sep 15 2017 - 18:44:36 EST


I'm announcing the release of the 3.2.93 kernel.

All users of the 3.2 kernel series should upgrade.

The updated 3.2.y git tree can be found at:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-3.2.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git

The diff from 3.2.92 is attached to this message.

Ben.

------------

Makefile | 2 +-
arch/alpha/kernel/osf_sys.c | 6 +-
arch/mips/include/asm/kprobes.h | 3 +-
arch/mips/kernel/entry.S | 3 +
arch/powerpc/include/asm/page.h | 12 +++
arch/powerpc/kernel/kprobes.c | 12 +++
arch/powerpc/kernel/setup_64.c | 25 ++++++
arch/x86/kvm/mmu.c | 7 +-
arch/x86/kvm/mmu.h | 1 +
arch/x86/kvm/x86.c | 53 ++++++++-----
crypto/gcm.c | 6 +-
drivers/ata/ahci.c | 38 +++++++++
drivers/char/mem.c | 5 ++
drivers/dma/ep93xx_dma.c | 2 +
drivers/gpu/drm/radeon/radeon_combios.c | 7 ++
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 2 +
drivers/i2c/busses/i2c-tiny-usb.c | 25 +++++-
drivers/input/serio/i8042-x86ia64io.h | 7 ++
drivers/media/rc/ir-raw.c | 13 ++--
drivers/media/video/videobuf2-core.c | 4 +-
drivers/net/ethernet/8390/ax88796.c | 7 +-
drivers/net/ethernet/ethoc.c | 3 +-
drivers/net/irda/irda-usb.c | 2 +-
drivers/net/phy/marvell.c | 68 ++++++++--------
drivers/of/fdt.c | 2 +
drivers/scsi/qla2xxx/qla_os.c | 8 +-
drivers/staging/gma500/psb_intel_lvds.c | 18 +++--
drivers/staging/usbip/vhci_hcd.c | 11 ++-
drivers/usb/core/devio.c | 4 +-
drivers/usb/core/hcd.c | 4 +-
drivers/usb/core/hub.c | 28 +++++--
drivers/usb/gadget/dummy_hcd.c | 6 +-
drivers/usb/gadget/f_mass_storage.c | 13 +++-
drivers/usb/host/r8a66597-hcd.c | 6 +-
drivers/usb/host/xhci-hub.c | 37 +++++++++
drivers/usb/host/xhci-mem.c | 2 +-
drivers/usb/host/xhci-pci.c | 16 +++-
drivers/usb/host/xhci-ring.c | 37 +++++----
drivers/usb/host/xhci.h | 3 +
drivers/usb/misc/iowarrior.c | 2 +-
drivers/usb/musb/tusb6010_omap.c | 13 +++-
drivers/usb/serial/ftdi_sio.c | 2 +-
drivers/usb/serial/io_ti.c | 5 +-
drivers/usb/serial/ir-usb.c | 21 ++---
drivers/usb/serial/mct_u232.c | 2 +-
drivers/usb/storage/ene_ub6250.c | 90 +++++++++++++---------
drivers/uwb/i1480/dfu/usb.c | 5 +-
drivers/watchdog/pcwd_usb.c | 3 +
drivers/xen/biomerge.c | 3 +-
fs/autofs4/dev-ioctl.c | 2 +-
fs/configfs/symlink.c | 3 +-
fs/ext4/extents.c | 2 +
fs/ext4/inode.c | 31 ++++++--
fs/partitions/check.c | 4 +-
fs/proc/array.c | 2 +-
fs/proc/base.c | 12 +--
fs/proc/namespaces.c | 4 +-
fs/ufs/inode.c | 5 +-
fs/ufs/super.c | 18 +++++
fs/ufs/truncate.c | 6 --
fs/ufs/util.h | 10 ++-
include/linux/kprobes.h | 4 +-
include/linux/ptrace.h | 24 +++++-
include/linux/skbuff.h | 1 +
include/linux/usb/ch11.h | 3 +
include/net/xfrm.h | 10 ---
kernel/events/core.c | 2 +-
kernel/futex.c | 2 +-
kernel/futex_compat.c | 2 +-
kernel/kprobes.c | 2 +-
kernel/ptrace.c | 39 ++++++++--
kernel/signal.c | 20 +++--
kernel/time/alarmtimer.c | 12 ++-
kernel/trace/trace_kprobe.c | 18 +++--
lib/cmdline.c | 6 +-
mm/mempolicy.c | 29 ++++---
mm/migrate.c | 45 +++++------
mm/page_cgroup.c | 3 +
mm/process_vm_access.c | 2 +-
net/ceph/osdmap.c | 1 +
net/core/dev.c | 2 +-
net/core/rtnetlink.c | 2 +
net/core/skbuff.c | 20 +++--
net/ipv4/af_inet.c | 2 +-
net/ipv4/tcp.c | 4 +
net/ipv4/tcp_input.c | 11 +--
net/ipv6/addrconf.c | 5 +-
net/ipv6/af_inet6.c | 4 +-
net/ipv6/xfrm6_mode_ro.c | 2 +
net/ipv6/xfrm6_mode_transport.c | 2 +
net/key/af_key.c | 19 +++--
net/mac80211/rx.c | 3 +-
net/netfilter/nf_conntrack_netlink.c | 7 +-
net/wireless/util.c | 14 +++-
net/xfrm/xfrm_policy.c | 51 ++----------
security/commoncap.c | 7 +-
security/keys/keyctl.c | 4 +-
security/selinux/hooks.c | 5 +-
sound/pci/hda/patch_sigmatel.c | 2 +
sound/soc/soc-core.c | 5 +-
tools/perf/Documentation/perf-probe.txt | 8 +-
tools/perf/Documentation/perf-script-perl.txt | 2 +-
tools/perf/Documentation/perf-script-python.txt | 23 +++---
.../util/scripting-engines/trace-event-python.c | 2 +-
104 files changed, 793 insertions(+), 391 deletions(-)

Al Viro (4):
osf_wait4(): fix infoleak
fix ufs_isblockset()
ufs: set correct ->s_maxsize
excessive checks in ufs_write_failed() and ufs_evict_inode()

Alan Stern (2):
USB: ene_usb6250: fix DMA to the stack
USB: xhci: fix lock-inversion problem

Alex Deucher (1):
drm/radeon: add a quirk for Toshiba Satellite L20-183

Alexander Sverdlin (1):
dmaengine: ep93xx: Always start from BASE0

Alexander Tsoy (1):
ALSA: hda - apply STAC_9200_DELL_M22 quirk for Dell Latitude D430

Andrew Lunn (1):
net: phy: marvell: Limit errata to 88m1101

Anthony Mallet (1):
USB: serial: ftdi_sio: fix setting latency for unprivileged users

Ben Hutchings (3):
ipv6: xfrm: Handle errors reported by xfrm6_find_1stfragopt()
net: add kfree_skb_list()
Linux 3.2.93

Chris Brandt (2):
usb: r8a66597-hcd: decrease timeout
usb: r8a66597-hcd: select a different endpoint on timeout

Christoph Lameter (1):
mm: fix move/migrate_pages() race on task struct

Christophe JAILLET (1):
vb2: Fix an off by one error in 'vb2_plane_vaddr'

Corentin Labbe (1):
usb: xhci: ASMedia ASM1042A chipset need shorts TX quirk

Dan Carpenter (5):
block: fix an error code in add_partition()
libceph: NULL deref on crush_decode() error path
drm/vmwgfx: Handle vmalloc() failure in vmw_local_fifo_reserve()
xfrm: Oops on error in pfkey_msg2xfrm_state()
xfrm: NULL dereference on allocation failure

Daniel Drake (1):
Input: i8042 - add Fujitsu Lifebook AH544 to notimeout list

David S. Miller (1):
ipv6: Fix leak in ipv6_gso_segment().

Eric Biggers (1):
KEYS: fix dereferencing NULL payload with nonzero length

Eric Dumazet (2):
net: ping: do not abuse udp_poll()
net: prevent sign extension in dev_get_stats()

Eric W. Biederman (1):
signal: Only reschedule timers on signals timers have sent

Felipe Balbi (1):
usb: host: xhci: simplify irq handler return

Gilad Ben-Yossef (1):
crypto: gcm - wait for crypto op not signal safe

Gleb Natapov (1):
KVM: x86: fix use of uninitialized memory as segment descriptor in emulator.

Ilya Matveychikov (1):
lib/cmdline.c: fix get_options() overflow while parsing ranges

Jan Kara (2):
ext4: fix data corruption for mmap writes
ext4: fix fdatasync(2) after extent manipulation operations

Jann Horn (1):
ptrace: use fsuid, fsgid, effective creds for fs access checks

Johan Hovold (13):
net: irda: irda-usb: fix firmware name on big-endian hosts
USB: serial: ir-usb: fix big-endian baud-rate debug printk
USB: serial: mct_u232: fix big-endian baud-rate handling
USB: serial: io_ti: fix div-by-zero in set_termios
uwb: fix device quirk on big-endian hosts
USB: iowarrior: fix info ioctl on big-endian hosts
USB: gadget: dummy_hcd: fix hub-descriptor removable fields
USB: usbip: fix nonconforming hub descriptor
USB: hub: fix SS hub-descriptor handling
USB: hub: fix non-SS hub-descriptor handling
USB: hub: fix SS max number of ports
of: fdt: add missing allocation-failure check
watchdog: pcwd_usb: fix NULL-deref at probe

Johannes Thumshirn (1):
scsi: qla2xxx: don't disable a not previously enabled PCI device

Julius Werner (2):
drivers: char: mem: Check for address space wraparound with mmap()
drivers: char: mem: Fix wraparound check to allow mappings up to the end

Konstantin Khlebnikov (1):
ext4: keep existing extra fields when inode expands

Linus Torvalds (1):
Sanitize 'move_pages()' permission checks

Liping Zhang (1):
netfilter: ctnetlink: fix incorrect nf_ct_put during hash resize

Marcin Nowakowski (1):
MIPS: kprobes: flush_insn_slot should flush only if probe initialised

Mathias Nyman (2):
xhci: workaround for hosts missing CAS bit
xhci: apply PME_STUCK_QUIRK and MISSING_CAS quirk for Denverton

Max Filippov (1):
net: ethoc: enable NAPI before poll may be scheduled

Michael Ellerman (1):
powerpc/mm: Fix virt_addr_valid() etc. on 64-bit hash

Naveen N. Rao (1):
powerpc/kprobes: Pause function_graph tracing during jprobes handling

NeilBrown (1):
autofs: sanity check status reported with AUTOFS_DEV_IOCTL_FAIL

Nicholas Bellinger (1):
configfs: Fix race between create_link and configfs_rmdir

Nicholas Piggin (1):
powerpc/64: Initialise thread_info for emergency stacks

Patrik Jakobsson (1):
drm/gma500/psb: Actually use VBT mode when it is found

Paul Burton (1):
MIPS: Fix IRQ tracing & lockdep when rescheduling

Paul Moore (1):
selinux: fix double free in selinux_parse_opts_str()

Peter Chen (1):
usb: host: xhci-mem: allocate zeroed Scratchpad Buffer

Peter Ujfalusi (1):
usb: musb: tusb6010_omap: Do not reset the other direction's packet size

Radim KrÄmÃÅ (1):
KVM: x86: zero base3 of unusable segments

Rajkumar Manoharan (1):
mac80211: strictly check mesh address extension mode

Roger Pau Monne (1):
xen: fix bio vec merging

Russell King (1):
net: phy: fix marvell phy status reading

Sabrina Dubroca (2):
xfrm: fix stack access out of bounds with CONFIG_XFRM_SUB_POLICY
tracing/kprobes: Allow to create probe with a module name starting with a digit

Sasha Levin (2):
mm: fix NULL ptr dereference in migrate_pages
mm: fix NULL ptr dereference in move_pages

Sean Young (1):
rc-core: race condition during ir_raw_event_register()

Sebastian Reichel (1):
i2c: i2c-tiny-usb: fix buffer not being DMA capable

SeongJae Park (6):
perf probe: Fix examples section of documentation
perf script: Fix outdated comment for perf-trace-python
perf script: Fix documentation errors
perf script python: Fix wrong code snippets in documentation
perf script python: Updated trace_unhandled() signature
perf script python: Remove dups in documentation examples

Serhey Popovych (1):
rtnetlink: add IFLA_GROUP to ifla_policy

Soheil Hassas Yeganeh (1):
tcp: eliminate negative reordering in tcp_clean_rtx_queue

Steffen Klassert (1):
af_key: Fix slab-out-of-bounds in pfkey_compile_policy.

Sui Chen (1):
ahci: Acer SA5-271 SSD Not Detected Fix

Takashi Iwai (1):
ASoC: Fix use-after-free at card unregistration

Thinh Nguyen (1):
usb: gadget: f_mass_storage: Serialize wake and sleep execution

Thomas Gleixner (3):
tracing/kprobes: Enforce kprobes teardown after testing
alarmtimer: Prevent overflow of relative timers
alarmtimer: Rate limit periodic intervals

Uwe Kleine-KÃnig (1):
net: ethernet: ax88796: don't call free_irq without request_irq first

Vamsi Krishna Samavedam (1):
USB: core: replace %p with %pK

Vladis Dronov (1):
xfrm: policy: check policy direction value

WANG Cong (1):
ipv6: avoid unregistering inet6_dev for loopback

Wan Ahmad Zainie (1):
usb: xhci: apply XHCI_PME_STUCK_QUIRK to Intel Apollo Lake

Wanpeng Li (3):
KVM: X86: Fix read out-of-bounds vulnerability in kvm pio emulation
KVM: cpuid: Fix read/write out-of-bounds vulnerability in cpuid emulation
KVM: async_pf: avoid async pf injection when in guest mode

Wei Wang (1):
tcp: initialize rcv_mss to TCP_MIN_MSS instead of 0

Yu Zhao (1):
swap: cond_resched in swap_cgroup_prepare()

Yuchung Cheng (1):
tcp: avoid fragmenting peculiar skbs in SACK

Zhaowei Yuan (1):
vb2: fix plane index sanity check in vb2_plane_cookie()

--
Ben Hutchings
Kids! Bringing about Armageddon can be dangerous. Do not attempt it in
your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'diff --git a/Makefile b/Makefile
index 2e85e1716900..ec64e6f97222 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 2
-SUBLEVEL = 92
+SUBLEVEL = 93
EXTRAVERSION =
NAME = Saber-toothed Squirrel

diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index b9abe5bb437b..13a99b4988a3 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -1026,8 +1026,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
return -EFAULT;

- err = 0;
- err |= put_user(status, ustatus);
+ err = put_user(status, ustatus);
+ if (ret < 0)
+ return err ? err : ret;
+
err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h
index e6ea4d4d7205..c271e278d723 100644
--- a/arch/mips/include/asm/kprobes.h
+++ b/arch/mips/include/asm/kprobes.h
@@ -40,7 +40,8 @@ typedef union mips_instruction kprobe_opcode_t;

#define flush_insn_slot(p) \
do { \
- flush_icache_range((unsigned long)p->addr, \
+ if (p->addr) \
+ flush_icache_range((unsigned long)p->addr, \
(unsigned long)p->addr + \
(MAX_INSN_SIZE * sizeof(kprobe_opcode_t))); \
} while (0)
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 37acfa036d44..5fc7a6475126 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -10,6 +10,7 @@

#include <asm/asm.h>
#include <asm/asmmacro.h>
+#include <asm/irqflags.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/stackframe.h>
@@ -145,6 +146,7 @@ FEXPORT(restore_partial) # restore partial frame
andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
beqz t0, work_notifysig
work_resched:
+ TRACE_IRQS_OFF
jal schedule

local_irq_disable # make sure need_resched and
@@ -172,6 +174,7 @@ FEXPORT(syscall_exit_work_partial)
beqz t0, work_pending # trace bit set?
local_irq_enable # could let syscall_trace_leave()
# call schedule() instead
+ TRACE_IRQS_ON
move a0, sp
jal syscall_trace_leave
b resume_userspace
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 5b0bde2f7dbd..516fadd9fdce 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -118,7 +118,19 @@ extern phys_addr_t kernstart_addr;

#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * On hash the vmalloc and other regions alias to the kernel region when passed
+ * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can
+ * return true for some vmalloc addresses, which is incorrect. So explicitly
+ * check that the address is in the kernel region.
+ */
+#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \
+ pfn_valid(__pa(kaddr) >> PAGE_SHIFT))
+#else
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#endif

/*
* On Book-E parts we need __va to parse the device tree and we can't
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index bc47352deb1f..fe3f4efcb849 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -32,6 +32,7 @@
#include <linux/module.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
+#include <linux/ftrace.h>
#include <asm/cacheflush.h>
#include <asm/sstep.h>
#include <asm/uaccess.h>
@@ -530,6 +531,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
#endif

+ /*
+ * jprobes use jprobe_return() which skips the normal return
+ * path of the function, and this messes up the accounting of the
+ * function graph tracer.
+ *
+ * Pause function graph tracing while performing the jprobe function.
+ */
+ pause_graph_tracing();
+
return 1;
}

@@ -552,6 +562,8 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
* saved regs...
*/
memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+ /* It's OK to start function graph tracing again */
+ unpause_graph_tracing();
preempt_enable_no_resched();
return 1;
}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 2c8890adcef1..50c959b2a664 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -508,6 +508,23 @@ static void __init exc_lvl_early_init(void)
#define exc_lvl_early_init()
#endif

+/*
+ * Emergency stacks are used for a range of things, from asynchronous
+ * NMIs (system reset, machine check) to synchronous, process context.
+ * We set preempt_count to zero, even though that isn't necessarily correct. To
+ * get the right value we'd need to copy it from the previous thread_info, but
+ * doing that might fault causing more problems.
+ * TODO: what to do with accounting?
+ */
+static void emerg_stack_init_thread_info(struct thread_info *ti, int cpu)
+{
+ ti->task = NULL;
+ ti->cpu = cpu;
+ ti->preempt_count = 0;
+ ti->local_flags = 0;
+ ti->flags = 0;
+}
+
/*
* Stack space used when we detect a bad kernel stack pointer, and
* early in SMP boots before relocation is enabled.
@@ -525,12 +542,20 @@ static void __init emergency_stack_init(void)
* Since we use these as temporary stacks during secondary CPU
* bringup, we need to get at them in real mode. This means they
* must also be within the RMO region.
+ *
+ * The IRQ stacks allocated elsewhere in this file are zeroed and
+ * initialized in kernel/irq.c. These are initialized here in order
+ * to have emergency stacks available as early as possible.
*/
limit = min(safe_stack_limit(), ppc64_rma_size);

for_each_possible_cpu(i) {
unsigned long sp;
+ struct thread_info *ti;
sp = memblock_alloc_base(THREAD_SIZE, THREAD_SIZE, limit);
+ ti = __va(sp);
+ memset(ti, 0, THREAD_SIZE);
+ emerg_stack_init_thread_info(ti, i);
sp += THREAD_SIZE;
paca[i].emergency_sp = __va(sp);
}
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 4a949c7f6423..5b2bf2b4acae 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -3011,12 +3011,15 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn)
return kvm_setup_async_pf(vcpu, gva, gfn, &arch);
}

-static bool can_do_async_pf(struct kvm_vcpu *vcpu)
+bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu)
{
if (unlikely(!irqchip_in_kernel(vcpu->kvm) ||
kvm_event_needs_reinjection(vcpu)))
return false;

+ if (is_guest_mode(vcpu))
+ return false;
+
return kvm_x86_ops->interrupt_allowed(vcpu);
}

@@ -3032,7 +3035,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,

put_page(pfn_to_page(*pfn));

- if (!prefault && can_do_async_pf(vcpu)) {
+ if (!prefault && kvm_can_do_async_pf(vcpu)) {
trace_kvm_try_async_get_page(gva, gfn);
if (kvm_find_async_pf_gfn(vcpu, gfn)) {
trace_kvm_async_pf_doublefault(gva, gfn);
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index e374db9af021..943198e63bdd 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -52,6 +52,7 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask);
int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct);
int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context);
+bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu);

static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm)
{
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d0284b49317b..c8c3c39f5bf7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4380,16 +4380,20 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,

static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
{
- /* TODO: String I/O for in kernel device */
- int r;
+ int r = 0, i;

- if (vcpu->arch.pio.in)
- r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
- vcpu->arch.pio.size, pd);
- else
- r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
- vcpu->arch.pio.port, vcpu->arch.pio.size,
- pd);
+ for (i = 0; i < vcpu->arch.pio.count; i++) {
+ if (vcpu->arch.pio.in)
+ r = kvm_io_bus_read(vcpu->kvm, KVM_PIO_BUS, vcpu->arch.pio.port,
+ vcpu->arch.pio.size, pd);
+ else
+ r = kvm_io_bus_write(vcpu->kvm, KVM_PIO_BUS,
+ vcpu->arch.pio.port, vcpu->arch.pio.size,
+ pd);
+ if (r)
+ break;
+ pd += vcpu->arch.pio.size;
+ }
return r;
}

@@ -4403,6 +4407,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
if (vcpu->arch.pio.count)
goto data_avail;

+ memset(vcpu->arch.pio_data, 0, size * count);
+
trace_kvm_pio(0, port, size, count);

vcpu->arch.pio.port = port;
@@ -4605,8 +4611,12 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
kvm_get_segment(emul_to_vcpu(ctxt), &var, seg);
*selector = var.selector;

- if (var.unusable)
+ if (var.unusable) {
+ memset(desc, 0, sizeof(*desc));
+ if (base3)
+ *base3 = 0;
return false;
+ }

if (var.g)
var.limit >>= 12;
@@ -5440,18 +5450,20 @@ int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
{
struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
- int j, nent = vcpu->arch.cpuid_nent;
+ struct kvm_cpuid_entry2 *ej;
+ int j = i;
+ int nent = vcpu->arch.cpuid_nent;

e->flags &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
/* when no next entry is found, the current entry[i] is reselected */
- for (j = i + 1; ; j = (j + 1) % nent) {
- struct kvm_cpuid_entry2 *ej = &vcpu->arch.cpuid_entries[j];
- if (ej->function == e->function) {
- ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
- return j;
- }
- }
- return 0; /* silence gcc, even though control never reaches here */
+ do {
+ j = (j + 1) % nent;
+ ej = &vcpu->arch.cpuid_entries[j];
+ } while (ej->function != e->function);
+
+ ej->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
+
+ return j;
}

/* find an entry with matching function, matching index (if needed), and that
@@ -6923,8 +6935,7 @@ bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
if (!(vcpu->arch.apf.msr_val & KVM_ASYNC_PF_ENABLED))
return true;
else
- return !kvm_event_needs_reinjection(vcpu) &&
- kvm_x86_ops->interrupt_allowed(vcpu);
+ return kvm_can_do_async_pf(vcpu);
}

EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
diff --git a/crypto/gcm.c b/crypto/gcm.c
index dd3bf30f260b..9f740857f9f9 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -140,10 +140,8 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,

err = crypto_ablkcipher_encrypt(&data->req);
if (err == -EINPROGRESS || err == -EBUSY) {
- err = wait_for_completion_interruptible(
- &data->result.completion);
- if (!err)
- err = data->result.err;
+ wait_for_completion(&data->result.completion);
+ err = data->result.err;
}

if (err)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index baeee8324138..93ace9bbd182 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1268,6 +1268,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
{}
#endif

+/*
+ * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected
+ * as DUMMY, or detected but eventually get a "link down" and never get up
+ * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the
+ * port_map may hold a value of 0x00.
+ *
+ * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports
+ * and can significantly reduce the occurrence of the problem.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=189471
+ */
+static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv,
+ struct pci_dev *pdev)
+{
+ static const struct dmi_system_id sysids[] = {
+ {
+ .ident = "Acer Switch Alpha 12",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271")
+ },
+ },
+ { }
+ };
+
+ if (dmi_check_system(sysids)) {
+ dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n");
+ if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) {
+ hpriv->port_map = 0x7;
+ hpriv->cap = 0xC734FF02;
+ }
+ }
+}
+
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
unsigned int board_id = ent->driver_data;
@@ -1407,6 +1441,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
"online status unreliable, applying workaround\n");
}

+
+ /* Acer SA5-271 workaround modifies private_data */
+ acer_sa5_271_workaround(hpriv, pdev);
+
/* CAP.NP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index b1ac8d419a73..d78365603952 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -322,6 +322,11 @@ static const struct vm_operations_struct mmap_mem_ops = {
static int mmap_mem(struct file *file, struct vm_area_struct *vma)
{
size_t size = vma->vm_end - vma->vm_start;
+ phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
+
+ /* It's illegal to wrap around the end of the physical address space. */
+ if (offset + (phys_addr_t)size - 1 < offset)
+ return -EINVAL;

if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
return -EINVAL;
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index b47e2b803faf..e1612b6069eb 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -300,6 +300,8 @@ static int m2p_hw_setup(struct ep93xx_dma_chan *edmac)
| M2P_CONTROL_ENABLE;
m2p_set_control(edmac, control);

+ edmac->buffer = 0;
+
return 0;
}

diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 87a677e91927..9ac606fffc0a 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -3406,6 +3406,13 @@ void radeon_combios_asic_init(struct drm_device *dev)
rdev->pdev->subsystem_vendor == 0x103c &&
rdev->pdev->subsystem_device == 0x280a)
return;
+ /* quirk for rs4xx Toshiba Sattellite L20-183 latop to make it resume
+ * - it hangs on resume inside the dynclk 1 table.
+ */
+ if (rdev->family == CHIP_RS400 &&
+ rdev->pdev->subsystem_vendor == 0x1179 &&
+ rdev->pdev->subsystem_device == 0xff31)
+ return;

/* DYN CLK 1 */
table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
index decca8251bfa..ea9358313b3f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c
@@ -368,6 +368,8 @@ void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes)
return fifo_state->static_buffer;
else {
fifo_state->dynamic_buffer = vmalloc(bytes);
+ if (!fifo_state->dynamic_buffer)
+ goto out_err;
return fifo_state->dynamic_buffer;
}
}
diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c
index d03b04002f0d..8c669d7ec42f 100644
--- a/drivers/i2c/busses/i2c-tiny-usb.c
+++ b/drivers/i2c/busses/i2c-tiny-usb.c
@@ -159,22 +159,39 @@ static int usb_read(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+ void *dmadata = kmalloc(len, GFP_KERNEL);
+ int ret;
+
+ if (!dmadata)
+ return -ENOMEM;

/* do control transfer */
- return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
+ ret = usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
- USB_DIR_IN, value, index, data, len, 2000);
+ USB_DIR_IN, value, index, dmadata, len, 2000);
+
+ memcpy(data, dmadata, len);
+ kfree(dmadata);
+ return ret;
}

static int usb_write(struct i2c_adapter *adapter, int cmd,
int value, int index, void *data, int len)
{
struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data;
+ void *dmadata = kmemdup(data, len, GFP_KERNEL);
+ int ret;
+
+ if (!dmadata)
+ return -ENOMEM;

/* do control transfer */
- return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
+ ret = usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0),
cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
- value, index, data, len, 2000);
+ value, index, dmadata, len, 2000);
+
+ kfree(dmadata);
+ return ret;
}

static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 8941d8ddd357..961e56b6a7c8 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -673,6 +673,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"),
},
},
+ {
+ /* Fujitsu UH554 laptop */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"),
+ },
+ },
{ }
};

diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c
index 2e5cd3100b64..3a5a5b60f1c6 100644
--- a/drivers/media/rc/ir-raw.c
+++ b/drivers/media/rc/ir-raw.c
@@ -225,7 +225,7 @@ void ir_raw_event_handle(struct rc_dev *dev)
{
unsigned long flags;

- if (!dev->raw)
+ if (!dev->raw || !dev->raw->thread)
return;

spin_lock_irqsave(&dev->raw->lock, flags);
@@ -252,6 +252,7 @@ int ir_raw_event_register(struct rc_dev *dev)
{
int rc;
struct ir_raw_handler *handler;
+ struct task_struct *thread;

if (!dev)
return -EINVAL;
@@ -269,14 +270,16 @@ int ir_raw_event_register(struct rc_dev *dev)
goto out;

spin_lock_init(&dev->raw->lock);
- dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
- "rc%ld", dev->devno);
+ thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%ld",
+ dev->devno);

- if (IS_ERR(dev->raw->thread)) {
- rc = PTR_ERR(dev->raw->thread);
+ if (IS_ERR(thread)) {
+ rc = PTR_ERR(thread);
goto out;
}

+ dev->raw->thread = thread;
+
mutex_lock(&ir_raw_handler_lock);
list_add_tail(&dev->raw->list, &ir_raw_client_list);
list_for_each_entry(handler, &ir_raw_handler_list, list)
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 95a3f5e82aef..92dfe2322d96 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -731,7 +731,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
{
struct vb2_queue *q = vb->vb2_queue;

- if (plane_no > vb->num_planes)
+ if (plane_no >= vb->num_planes)
return NULL;

return call_memop(q, plane_no, vaddr, vb->planes[plane_no].mem_priv);
@@ -754,7 +754,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
{
struct vb2_queue *q = vb->vb2_queue;

- if (plane_no > vb->num_planes)
+ if (plane_no >= vb->num_planes)
return NULL;

return call_memop(q, plane_no, cookie, vb->planes[plane_no].mem_priv);
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c
index e9f8432f55b4..fdffd122f5cb 100644
--- a/drivers/net/ethernet/8390/ax88796.c
+++ b/drivers/net/ethernet/8390/ax88796.c
@@ -769,13 +769,13 @@ static int ax_init_dev(struct net_device *dev)

ret = ax_mii_init(dev);
if (ret)
- goto out_irq;
+ goto err_out;

ax_NS8390_init(dev, 0);

ret = register_netdev(dev);
if (ret)
- goto out_irq;
+ goto err_out;

netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n",
ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr,
@@ -783,9 +783,6 @@ static int ax_init_dev(struct net_device *dev)

return 0;

- out_irq:
- /* cleanup irq */
- free_irq(dev->irq, dev);
err_out:
return ret;
}
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index b3b22f487b41..ba5c4a997190 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -703,6 +703,8 @@ static int ethoc_open(struct net_device *dev)
if (ret)
return ret;

+ napi_enable(&priv->napi);
+
ethoc_init_ring(priv, dev->mem_start);
ethoc_reset(priv);

@@ -715,7 +717,6 @@ static int ethoc_open(struct net_device *dev)
}

phy_start(priv->phy);
- napi_enable(&priv->napi);

if (netif_msg_ifup(priv)) {
dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index d9267cb98a23..6b4f49ed3690 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1083,7 +1083,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self)
* are "42101001.sb" or "42101002.sb"
*/
sprintf(stir421x_fw_name, "4210%4X.sb",
- self->usbdev->descriptor.bcdDevice);
+ le16_to_cpu(self->usbdev->descriptor.bcdDevice));
ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev);
if (ret < 0)
return ret;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index e8b9c53c304b..4915d106f94b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -126,34 +126,6 @@ static int marvell_config_aneg(struct phy_device *phydev)
{
int err;

- /* The Marvell PHY has an errata which requires
- * that certain registers get written in order
- * to restart autonegotiation */
- err = phy_write(phydev, MII_BMCR, BMCR_RESET);
-
- if (err < 0)
- return err;
-
- err = phy_write(phydev, 0x1d, 0x1f);
- if (err < 0)
- return err;
-
- err = phy_write(phydev, 0x1e, 0x200c);
- if (err < 0)
- return err;
-
- err = phy_write(phydev, 0x1d, 0x5);
- if (err < 0)
- return err;
-
- err = phy_write(phydev, 0x1e, 0);
- if (err < 0)
- return err;
-
- err = phy_write(phydev, 0x1e, 0x100);
- if (err < 0)
- return err;
-
err = phy_write(phydev, MII_M1011_PHY_SCR,
MII_M1011_PHY_SCR_AUTO_CROSS);
if (err < 0)
@@ -188,6 +160,42 @@ static int marvell_config_aneg(struct phy_device *phydev)
return 0;
}

+static int m88e1101_config_aneg(struct phy_device *phydev)
+{
+ int err;
+
+ /* This Marvell PHY has an errata which requires
+ * that certain registers get written in order
+ * to restart autonegotiation
+ */
+ err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, 0x1d, 0x1f);
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, 0x1e, 0x200c);
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, 0x1d, 0x5);
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, 0x1e, 0);
+ if (err < 0)
+ return err;
+
+ err = phy_write(phydev, 0x1e, 0x100);
+ if (err < 0)
+ return err;
+
+ return marvell_config_aneg(phydev);
+}
+
#ifdef CONFIG_OF_MDIO
/*
* Set and/or override some configuration registers based on the
@@ -653,8 +661,6 @@ static int marvell_read_status(struct phy_device *phydev)
if (adv < 0)
return adv;

- lpa &= adv;
-
if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
phydev->duplex = DUPLEX_FULL;
else
@@ -724,7 +730,7 @@ static struct phy_driver marvell_drivers[] = {
.name = "Marvell 88E1101",
.features = PHY_GBIT_FEATURES,
.flags = PHY_HAS_INTERRUPT,
- .config_aneg = &marvell_config_aneg,
+ .config_aneg = &m88e1101_config_aneg,
.read_status = &genphy_read_status,
.ack_interrupt = &marvell_ack_interrupt,
.config_intr = &marvell_config_intr,
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index b77808c4daa8..29f121e9345b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -388,6 +388,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob,
/* Allocate memory for the expanded device tree */
mem = (unsigned long)
dt_alloc(size + 4, __alignof__(struct device_node));
+ if (!mem)
+ return NULL;

memset((void *)mem, 0, size);

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 82a5ca64ca71..6cda887fa797 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1999,10 +1999,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)

if (mem_only) {
if (pci_enable_device_mem(pdev))
- goto probe_out;
+ return ret;
} else {
if (pci_enable_device(pdev))
- goto probe_out;
+ return ret;
}

/* This may fail but that's ok */
@@ -2012,7 +2012,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (!ha) {
ql_log_pci(ql_log_fatal, pdev, 0x0009,
"Unable to allocate memory for ha.\n");
- goto probe_out;
+ goto disable_device;
}
ql_dbg_pci(ql_dbg_init, pdev, 0x000a,
"Memory allocated for ha=%p.\n", ha);
@@ -2433,7 +2433,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
kfree(ha);
ha = NULL;

-probe_out:
+disable_device:
pci_disable_device(pdev);
return ret;
}
diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
index 21022e1a977a..8e2afbb73529 100644
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ b/drivers/staging/gma500/psb_intel_lvds.c
@@ -792,20 +792,23 @@ void psb_intel_lvds_init(struct drm_device *dev,
if (scan->type & DRM_MODE_TYPE_PREFERRED) {
mode_dev->panel_fixed_mode =
drm_mode_duplicate(dev, scan);
+ DRM_DEBUG_KMS("Using mode from DDC\n");
goto out; /* FIXME: check for quirks */
}
}

/* Failed to get EDID, what about VBT? do we need this? */
- if (mode_dev->vbt_mode)
+ if (dev_priv->lfp_lvds_vbt_mode) {
mode_dev->panel_fixed_mode =
- drm_mode_duplicate(dev, mode_dev->vbt_mode);
+ drm_mode_duplicate(dev, dev_priv->lfp_lvds_vbt_mode);

- if (!mode_dev->panel_fixed_mode)
- if (dev_priv->lfp_lvds_vbt_mode)
- mode_dev->panel_fixed_mode =
- drm_mode_duplicate(dev,
- dev_priv->lfp_lvds_vbt_mode);
+ if (mode_dev->panel_fixed_mode) {
+ mode_dev->panel_fixed_mode->type |=
+ DRM_MODE_TYPE_PREFERRED;
+ DRM_DEBUG_KMS("Using mode from VBT\n");
+ goto out;
+ }
+ }

/*
* If we didn't get EDID, try checking if the panel is already turned
@@ -822,6 +825,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
if (mode_dev->panel_fixed_mode) {
mode_dev->panel_fixed_mode->type |=
DRM_MODE_TYPE_PREFERRED;
+ DRM_DEBUG_KMS("Using pre-programmed mode\n");
goto out; /* FIXME: check for quirks */
}
}
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index 2ee97e2095b0..68f9af85b9cb 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -248,14 +248,19 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
/* See hub_configure in hub.c */
static inline void hub_descriptor(struct usb_hub_descriptor *desc)
{
+ int width;
+
memset(desc, 0, sizeof(*desc));
desc->bDescriptorType = 0x29;
- desc->bDescLength = 9;
desc->wHubCharacteristics = (__force __u16)
(__constant_cpu_to_le16(0x0001));
+
desc->bNbrPorts = VHCI_NPORTS;
- desc->u.hs.DeviceRemovable[0] = 0xff;
- desc->u.hs.DeviceRemovable[1] = 0xff;
+ BUILD_BUG_ON(VHCI_NPORTS > USB_MAXCHILDREN);
+ width = desc->bNbrPorts / 8 + 1;
+ desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * width;
+ memset(&desc->u.hs.DeviceRemovable[0], 0, width);
+ memset(&desc->u.hs.DeviceRemovable[width], 0xff, width);
}

static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 45d3007cf86e..6f34a265f9ec 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -325,11 +325,11 @@ static void snoop_urb(struct usb_device *udev,

if (userurb) { /* Async */
if (when == SUBMIT)
- dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+ dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
"length %u\n",
userurb, ep, t, d, length);
else
- dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+ dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
"actual_length %u status %d\n",
userurb, ep, t, d, length,
timeout_or_status);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index eb2c3bd28db0..3cedf914bbab 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1563,7 +1563,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
if (retval == 0)
retval = -EINPROGRESS;
else if (retval != -EIDRM && retval != -EBUSY)
- dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
+ dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
urb, retval);
usb_put_dev(udev);
}
@@ -1645,7 +1645,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
/* kick hcd */
unlink1(hcd, urb, -ESHUTDOWN);
dev_dbg (hcd->self.controller,
- "shutdown urb %p ep%d%s%s\n",
+ "shutdown urb %pK ep%d%s%s\n",
urb, usb_endpoint_num(&ep->desc),
is_in ? "in" : "out",
({ char *s;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d2c7b4eecb2f..7c5946640888 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -177,7 +177,8 @@ static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
}

/* USB 2.0 spec Section 11.24.4.5 */
-static int get_hub_descriptor(struct usb_device *hdev, void *data)
+static int get_hub_descriptor(struct usb_device *hdev,
+ struct usb_hub_descriptor *desc)
{
int i, ret, size;
unsigned dtype;
@@ -193,10 +194,18 @@ static int get_hub_descriptor(struct usb_device *hdev, void *data)
for (i = 0; i < 3; i++) {
ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
- dtype << 8, 0, data, size,
+ dtype << 8, 0, desc, size,
USB_CTRL_GET_TIMEOUT);
- if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))
+ if (hub_is_superspeed(hdev)) {
+ if (ret == size)
+ return ret;
+ } else if (ret >= USB_DT_HUB_NONVAR_SIZE + 2) {
+ /* Make sure we have the DeviceRemovable field. */
+ size = USB_DT_HUB_NONVAR_SIZE + desc->bNbrPorts / 8 + 1;
+ if (ret < size)
+ return -EMSGSIZE;
return ret;
+ }
}
return -EINVAL;
}
@@ -1099,6 +1108,7 @@ static int hub_configure(struct usb_hub *hub,
unsigned int pipe;
int maxp, ret;
char *message = "out of memory";
+ unsigned maxchild;

hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
if (!hub->buffer) {
@@ -1113,7 +1123,7 @@ static int hub_configure(struct usb_hub *hub,
}
mutex_init(&hub->status_mutex);

- hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+ hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
if (!hub->descriptor) {
ret = -ENOMEM;
goto fail;
@@ -1121,13 +1131,19 @@ static int hub_configure(struct usb_hub *hub,

/* Request the entire hub descriptor.
* hub->descriptor can handle USB_MAXCHILDREN ports,
- * but the hub can/will return fewer bytes here.
+ * but a (non-SS) hub can/will return fewer bytes here.
*/
ret = get_hub_descriptor(hdev, hub->descriptor);
if (ret < 0) {
message = "can't read hub descriptor";
goto fail;
- } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
+ }
+
+ maxchild = USB_MAXCHILDREN;
+ if (hub_is_superspeed(hdev))
+ maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS);
+
+ if (hub->descriptor->bNbrPorts > maxchild) {
message = "hub has too many ports!";
ret = -ENODEV;
goto fail;
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 8e0a1bd92a54..03a9222a03b3 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1770,7 +1770,7 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc)
desc->wHubCharacteristics = cpu_to_le16(0x0001);
desc->bNbrPorts = 1;
desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
- desc->u.ss.DeviceRemovable = 0xffff;
+ desc->u.ss.DeviceRemovable = 0;
}

static inline void
@@ -1781,8 +1781,8 @@ hub_descriptor (struct usb_hub_descriptor *desc)
desc->bDescLength = 9;
desc->wHubCharacteristics = cpu_to_le16(0x0001);
desc->bNbrPorts = 1;
- desc->u.hs.DeviceRemovable[0] = 0xff;
- desc->u.hs.DeviceRemovable[1] = 0xff;
+ desc->u.hs.DeviceRemovable[0] = 0;
+ desc->u.hs.DeviceRemovable[1] = 0xff; /* PortPwrCtrlMask */
}

static int dummy_hub_control (
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 8d7fb6bfd617..21472b26b33a 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -512,7 +512,11 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
/* Caller must hold fsg->lock */
static void wakeup_thread(struct fsg_common *common)
{
- smp_wmb(); /* ensure the write of bh->state is complete */
+ /*
+ * Ensure the reading of thread_wakeup_needed
+ * and the writing of bh->state are completed
+ */
+ smp_mb();
/* Tell the main thread that something has happened */
common->thread_wakeup_needed = 1;
if (common->thread_task)
@@ -732,7 +736,12 @@ static int sleep_thread(struct fsg_common *common)
}
__set_current_state(TASK_RUNNING);
common->thread_wakeup_needed = 0;
- smp_rmb(); /* ensure the latest bh->state is visible */
+
+ /*
+ * Ensure the writing of thread_wakeup_needed
+ * and the reading of bh->state are completed
+ */
+ smp_mb();
return rc;
}

diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index e84ca1928dbf..fa5482c2ebab 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1274,7 +1274,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
time = 30;
break;
default:
- time = 300;
+ time = 50;
break;
}

@@ -1790,6 +1790,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
pipe = td->pipe;
pipe_stop(r8a66597, pipe);

+ /* Select a different address or endpoint */
new_td = td;
do {
list_move_tail(&new_td->queue,
@@ -1799,7 +1800,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
new_td = td;
break;
}
- } while (td != new_td && td->address == new_td->address);
+ } while (td != new_td && td->address == new_td->address &&
+ td->pipe->info.epnum == new_td->pipe->info.epnum);

start_transfer(r8a66597, new_td);

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 13bb316e832b..d89b72c86b66 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1036,6 +1036,35 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
return 0;
}

+/*
+ * Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
+ * warm reset a USB3 device stuck in polling or compliance mode after resume.
+ * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
+ */
+static bool xhci_port_missing_cas_quirk(int port_index,
+ __le32 __iomem **port_array)
+{
+ u32 portsc;
+
+ portsc = readl(port_array[port_index]);
+
+ /* if any of these are set we are not stuck */
+ if (portsc & (PORT_CONNECT | PORT_CAS))
+ return false;
+
+ if (((portsc & PORT_PLS_MASK) != XDEV_POLLING) &&
+ ((portsc & PORT_PLS_MASK) != XDEV_COMP_MODE))
+ return false;
+
+ /* clear wakeup/change bits, and do a warm port reset */
+ portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+ portsc |= PORT_WR;
+ writel(portsc, port_array[port_index]);
+ /* flush write */
+ readl(port_array[port_index]);
+ return true;
+}
+
int xhci_bus_resume(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -1070,6 +1099,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
int slot_id;

temp = xhci_readl(xhci, port_array[port_index]);
+
+ /* warm reset CAS limited ports stuck in polling/compliance */
+ if ((xhci->quirks & XHCI_MISSING_CAS) &&
+ (hcd->speed >= HCD_USB3) &&
+ xhci_port_missing_cas_quirk(port_index, port_array)) {
+ xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+ continue;
+ }
if (DEV_SUPERSPEED(temp))
temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
else
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 337b86695dfc..841eb6878e97 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1591,7 +1591,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
if (!xhci->scratchpad)
goto fail_sp;

- xhci->scratchpad->sp_array = dma_alloc_coherent(dev,
+ xhci->scratchpad->sp_array = dma_zalloc_coherent(dev,
num_sp * sizeof(u64),
&xhci->scratchpad->sp_dma, flags);
if (!xhci->scratchpad->sp_array)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index fce63553f397..423700bd310d 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -42,6 +42,8 @@
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f
#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8
#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8
+#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8
+#define PCI_DEVICE_ID_INTEL_DNV_XHCI 0x19d0

static const char hcd_name[] = "xhci_hcd";

@@ -138,9 +140,17 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
+ pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) {
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
}
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+ (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
+ xhci->quirks |= XHCI_MISSING_CAS;
+
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
xhci->quirks |= XHCI_RESET_ON_RESUME;
@@ -149,6 +159,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
}
if (pdev->vendor == PCI_VENDOR_ID_VIA)
xhci->quirks |= XHCI_RESET_ON_RESUME;
+
+ if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
+ pdev->device == 0x1142)
+ xhci->quirks |= XHCI_TRUST_TX_LENGTH;
}

/*
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 35e1b8461bff..74ed2108ea0f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2642,29 +2642,31 @@ static int xhci_handle_event(struct xhci_hcd *xhci)
irqreturn_t xhci_irq(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- u32 status;
union xhci_trb *trb;
- u64 temp_64;
union xhci_trb *event_ring_deq;
+ irqreturn_t ret = IRQ_NONE;
+ unsigned long flags;
dma_addr_t deq;
+ u64 temp_64;
+ u32 status;

- spin_lock(&xhci->lock);
+ spin_lock_irqsave(&xhci->lock, flags);
trb = xhci->event_ring->dequeue;
/* Check if the xHC generated the interrupt, or the irq is shared */
status = xhci_readl(xhci, &xhci->op_regs->status);
- if (status == 0xffffffff)
- goto hw_died;
-
- if (!(status & STS_EINT)) {
- spin_unlock(&xhci->lock);
- return IRQ_NONE;
+ if (status == 0xffffffff) {
+ ret = IRQ_HANDLED;
+ goto out;
}
+
+ if (!(status & STS_EINT))
+ goto out;
+
if (status & STS_FATAL) {
xhci_warn(xhci, "WARNING: Host System Error\n");
xhci_halt(xhci);
-hw_died:
- spin_unlock(&xhci->lock);
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
+ goto out;
}

/*
@@ -2694,9 +2696,8 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
xhci_write_64(xhci, temp_64 | ERST_EHB,
&xhci->ir_set->erst_dequeue);
- spin_unlock(&xhci->lock);
-
- return IRQ_HANDLED;
+ ret = IRQ_HANDLED;
+ goto out;
}

event_ring_deq = xhci->event_ring->dequeue;
@@ -2721,10 +2722,12 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
/* Clear the event handler busy flag (RW1C); event ring is empty. */
temp_64 |= ERST_EHB;
xhci_write_64(xhci, temp_64, &xhci->ir_set->erst_dequeue);
+ ret = IRQ_HANDLED;

- spin_unlock(&xhci->lock);
+out:
+ spin_unlock_irqrestore(&xhci->lock, flags);

- return IRQ_HANDLED;
+ return ret;
}

irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 15f58d1367ba..4453f2a3805e 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -280,6 +280,8 @@ struct xhci_op_regs {
#define XDEV_U0 (0x0 << 5)
#define XDEV_U2 (0x2 << 5)
#define XDEV_U3 (0x3 << 5)
+#define XDEV_POLLING (0x7 << 5)
+#define XDEV_COMP_MODE (0xa << 5)
#define XDEV_RESUME (0xf << 5)
/* true: port has power (see HCC_PPC) */
#define PORT_POWER (1 << 9)
@@ -1499,6 +1501,7 @@ struct xhci_hcd {
#define XHCI_SLOW_SUSPEND (1 << 17)
#define XHCI_SPURIOUS_WAKEUP (1 << 18)
#define XHCI_PME_STUCK_QUIRK (1 << 20)
+#define XHCI_MISSING_CAS (1 << 24)
unsigned int num_active_eps;
unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 878a346d743d..097e4ef04592 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -560,7 +560,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);

/* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
- info.speed = le16_to_cpu(dev->udev->speed);
+ info.speed = dev->udev->speed;
info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
info.report_size = dev->report_size;

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index b67b4bc596c1..659960b1a98c 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -237,6 +237,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
u32 dma_remaining;
int src_burst, dst_burst;
u16 csr;
+ u32 psize;
int ch;
s8 dmareq;
s8 sync_dev;
@@ -408,15 +409,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,

if (chdat->tx) {
/* Send transfer_packet_sz packets at a time */
- musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
- chdat->transfer_packet_sz);
+ psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+ psize &= ~0x7ff;
+ psize |= chdat->transfer_packet_sz;
+ musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);

musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
} else {
/* Receive transfer_packet_sz packets at a time */
- musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
- chdat->transfer_packet_sz << 16);
+ psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+ psize &= ~(0x7ff << 16);
+ psize |= (chdat->transfer_packet_sz << 16);
+ musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);

musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c298c7a05842..a42adabce86a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1543,9 +1543,9 @@ static int set_serial_info(struct tty_struct *tty,
(new_serial.flags & ASYNC_FLAGS));
priv->custom_divisor = new_serial.custom_divisor;

+check_and_exit:
write_latency_timer(port);

-check_and_exit:
if ((old_priv.flags & ASYNC_SPD_MASK) !=
(priv->flags & ASYNC_SPD_MASK)) {
if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index a4177561d09a..86c8efd49583 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2412,8 +2412,11 @@ static void change_port_settings(struct tty_struct *tty,
if (!baud) {
/* pick a default, any default... */
baud = 9600;
- } else
+ } else {
+ /* Avoid a zero divisor. */
+ baud = min(baud, 461550);
tty_encode_baud_rate(tty, baud, baud);
+ }

edge_port->baud_rate = baud;
config->wBaudRate = (__u16)((461550L + baud/2) / baud);
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index ccbce4066d04..b0236abe8f16 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -236,6 +236,7 @@ static u8 ir_xbof_change(u8 xbof)
static int ir_startup(struct usb_serial *serial)
{
struct usb_irda_cs_descriptor *irda_desc;
+ int rates;

irda_desc = irda_usb_find_class_desc(serial->dev, 0);
if (!irda_desc) {
@@ -244,17 +245,19 @@ static int ir_startup(struct usb_serial *serial)
return -ENODEV;
}

+ rates = le16_to_cpu(irda_desc->wBaudRate);
+
dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
__func__,
- (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "",
- (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : "");
+ (rates & USB_IRDA_BR_2400) ? " 2400" : "",
+ (rates & USB_IRDA_BR_9600) ? " 9600" : "",
+ (rates & USB_IRDA_BR_19200) ? " 19200" : "",
+ (rates & USB_IRDA_BR_38400) ? " 38400" : "",
+ (rates & USB_IRDA_BR_57600) ? " 57600" : "",
+ (rates & USB_IRDA_BR_115200) ? " 115200" : "",
+ (rates & USB_IRDA_BR_576000) ? " 576000" : "",
+ (rates & USB_IRDA_BR_1152000) ? " 1152000" : "",
+ (rates & USB_IRDA_BR_4000000) ? " 4000000" : "");

switch (irda_desc->bmAdditionalBOFs) {
case USB_IRDA_AB_48:
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 801c697148ef..ed8694b1a0f4 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -251,7 +251,7 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
return -ENOMEM;

divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
- put_unaligned_le32(cpu_to_le32(divisor), buf);
+ put_unaligned_le32(divisor, buf);
rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
MCT_U232_SET_BAUD_RATE_REQUEST,
MCT_U232_SET_REQUEST_TYPE,
diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c
index 9fbe742343c6..8f6fa2d2ec0b 100644
--- a/drivers/usb/storage/ene_ub6250.c
+++ b/drivers/usb/storage/ene_ub6250.c
@@ -431,6 +431,10 @@ struct ms_lib_ctrl {
#define SD_BLOCK_LEN 9

struct ene_ub6250_info {
+
+ /* I/O bounce buffer */
+ u8 *bbuf;
+
/* for 6250 code */
struct SD_STATUS SD_Status;
struct MS_STATUS MS_Status;
@@ -478,8 +482,11 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag);

static void ene_ub6250_info_destructor(void *extra)
{
+ struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
+
if (!extra)
return;
+ kfree(info->bbuf);
}

static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
@@ -843,8 +850,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
{
struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+ u8 *bbuf = info->bbuf;
int result;
- u8 ExtBuf[4];
u32 bn = PhyBlockAddr * 0x20 + PageNum;

/* printk(KERN_INFO "MS --- MS_ReaderReadPage,
@@ -887,7 +895,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
bcb->CDB[2] = (unsigned char)(PhyBlockAddr>>16);
bcb->CDB[6] = 0x01;

- result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;

@@ -896,9 +904,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
ExtraDat->status0 = 0x10; /* Not yet,fireware support */

ExtraDat->status1 = 0x00; /* Not yet,fireware support */
- ExtraDat->ovrflg = ExtBuf[0];
- ExtraDat->mngflg = ExtBuf[1];
- ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+ ExtraDat->ovrflg = bbuf[0];
+ ExtraDat->mngflg = bbuf[1];
+ ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);

return USB_STOR_TRANSPORT_GOOD;
}
@@ -1324,8 +1332,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
{
struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+ struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+ u8 *bbuf = info->bbuf;
int result;
- u8 ExtBuf[4];

/* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum); */
memset(bcb, 0, sizeof(struct bulk_cb_wrap));
@@ -1340,7 +1349,7 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
bcb->CDB[2] = (unsigned char)(PhyBlock>>16);
bcb->CDB[6] = 0x01;

- result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;

@@ -1348,9 +1357,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
ExtraDat->intr = 0x80; /* Not yet, waiting for fireware support */
ExtraDat->status0 = 0x10; /* Not yet, waiting for fireware support */
ExtraDat->status1 = 0x00; /* Not yet, waiting for fireware support */
- ExtraDat->ovrflg = ExtBuf[0];
- ExtraDat->mngflg = ExtBuf[1];
- ExtraDat->logadr = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+ ExtraDat->ovrflg = bbuf[0];
+ ExtraDat->mngflg = bbuf[1];
+ ExtraDat->logadr = memstick_logaddr(bbuf[2], bbuf[3]);

return USB_STOR_TRANSPORT_GOOD;
}
@@ -1554,9 +1563,9 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
u16 PhyBlock, newblk, i;
u16 LogStart, LogEnde;
struct ms_lib_type_extdat extdat;
- u8 buf[0x200];
u32 count = 0, index = 0;
struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+ u8 *bbuf = info->bbuf;

for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
@@ -1570,14 +1579,16 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
}

if (count == PhyBlock) {
- ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf);
+ ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
+ bbuf);
count += 0x80;
}
index = (PhyBlock % 0x80) * 4;

- extdat.ovrflg = buf[index];
- extdat.mngflg = buf[index+1];
- extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]);
+ extdat.ovrflg = bbuf[index];
+ extdat.mngflg = bbuf[index+1];
+ extdat.logadr = memstick_logaddr(bbuf[index+2],
+ bbuf[index+3]);

if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
ms_lib_setacquired_errorblock(us, PhyBlock);
@@ -2066,9 +2077,9 @@ static int ene_ms_init(struct us_data *us)
{
struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
int result;
- u8 buf[0x200];
u16 MSP_BlockSize, MSP_UserAreaBlocks;
struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+ u8 *bbuf = info->bbuf;

printk(KERN_INFO "transport --- ENE_MSInit\n");

@@ -2087,13 +2098,13 @@ static int ene_ms_init(struct us_data *us)
bcb->CDB[0] = 0xF1;
bcb->CDB[1] = 0x01;

- result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
if (result != USB_STOR_XFER_GOOD) {
printk(KERN_ERR "Execution MS Init Code Fail !!\n");
return USB_STOR_TRANSPORT_ERROR;
}
/* the same part to test ENE */
- info->MS_Status = *(struct MS_STATUS *)&buf[0];
+ info->MS_Status = *(struct MS_STATUS *) bbuf;

if (info->MS_Status.Insert && info->MS_Status.Ready) {
printk(KERN_INFO "Insert = %x\n", info->MS_Status.Insert);
@@ -2102,15 +2113,15 @@ static int ene_ms_init(struct us_data *us)
printk(KERN_INFO "IsMSPHG = %x\n", info->MS_Status.IsMSPHG);
printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
if (info->MS_Status.IsMSPro) {
- MSP_BlockSize = (buf[6] << 8) | buf[7];
- MSP_UserAreaBlocks = (buf[10] << 8) | buf[11];
+ MSP_BlockSize = (bbuf[6] << 8) | bbuf[7];
+ MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
} else {
ms_card_init(us); /* Card is MS (to ms.c)*/
}
US_DEBUGP("MS Init Code OK !!\n");
} else {
- US_DEBUGP("MS Card Not Ready --- %x\n", buf[0]);
+ US_DEBUGP("MS Card Not Ready --- %x\n", bbuf[0]);
return USB_STOR_TRANSPORT_ERROR;
}

@@ -2120,9 +2131,9 @@ static int ene_ms_init(struct us_data *us)
static int ene_sd_init(struct us_data *us)
{
int result;
- u8 buf[0x200];
struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+ u8 *bbuf = info->bbuf;

US_DEBUGP("transport --- ENE_SDInit\n");
/* SD Init Part-1 */
@@ -2156,15 +2167,15 @@ static int ene_sd_init(struct us_data *us)
bcb->Flags = 0x80;
bcb->CDB[0] = 0xF1;

- result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+ result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP("Execution SD Init Code Fail !!\n");
return USB_STOR_TRANSPORT_ERROR;
}

- info->SD_Status = *(struct SD_STATUS *)&buf[0];
+ info->SD_Status = *(struct SD_STATUS *) bbuf;
if (info->SD_Status.Insert && info->SD_Status.Ready) {
- ene_get_card_status(us, (unsigned char *)&buf);
+ ene_get_card_status(us, bbuf);
US_DEBUGP("Insert = %x\n", info->SD_Status.Insert);
US_DEBUGP("Ready = %x\n", info->SD_Status.Ready);
US_DEBUGP("IsMMC = %x\n", info->SD_Status.IsMMC);
@@ -2172,7 +2183,7 @@ static int ene_sd_init(struct us_data *us)
US_DEBUGP("HiSpeed = %x\n", info->SD_Status.HiSpeed);
US_DEBUGP("WtP = %x\n", info->SD_Status.WtP);
} else {
- US_DEBUGP("SD Card Not Ready --- %x\n", buf[0]);
+ US_DEBUGP("SD Card Not Ready --- %x\n", bbuf[0]);
return USB_STOR_TRANSPORT_ERROR;
}
return USB_STOR_TRANSPORT_GOOD;
@@ -2182,13 +2193,15 @@ static int ene_sd_init(struct us_data *us)
static int ene_init(struct us_data *us)
{
int result;
- u8 misc_reg03 = 0;
+ u8 misc_reg03;
struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
+ u8 *bbuf = info->bbuf;

- result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+ result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;

+ misc_reg03 = bbuf[0];
if (misc_reg03 & 0x01) {
if (!info->SD_Status.Ready) {
result = ene_sd_init(us);
@@ -2304,8 +2317,9 @@ static int ene_ub6250_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
int result;
- u8 misc_reg03 = 0;
+ u8 misc_reg03;
struct us_data *us;
+ struct ene_ub6250_info *info;

result = usb_stor_probe1(&us, intf, id,
(id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list);
@@ -2313,11 +2327,16 @@ static int ene_ub6250_probe(struct usb_interface *intf,
return result;

/* FIXME: where should the code alloc extra buf ? */
- if (!us->extra) {
- us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
- if (!us->extra)
- return -ENOMEM;
- us->extra_destructor = ene_ub6250_info_destructor;
+ us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
+ if (!us->extra)
+ return -ENOMEM;
+ us->extra_destructor = ene_ub6250_info_destructor;
+
+ info = (struct ene_ub6250_info *)(us->extra);
+ info->bbuf = kmalloc(512, GFP_KERNEL);
+ if (!info->bbuf) {
+ kfree(us->extra);
+ return -ENOMEM;
}

us->transport_name = "ene_ub6250";
@@ -2329,12 +2348,13 @@ static int ene_ub6250_probe(struct usb_interface *intf,
return result;

/* probe card type */
- result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+ result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
if (result != USB_STOR_XFER_GOOD) {
usb_stor_disconnect(intf);
return USB_STOR_TRANSPORT_ERROR;
}

+ misc_reg03 = info->bbuf[0];
if (!(misc_reg03 & 0x01)) {
pr_info("ums_eneub6250: The driver only supports SD/MS card. "
"To use SM card, please build driver/staging/keucr\n");
diff --git a/drivers/uwb/i1480/dfu/usb.c b/drivers/uwb/i1480/dfu/usb.c
index b71291b5056f..a0102f802abb 100644
--- a/drivers/uwb/i1480/dfu/usb.c
+++ b/drivers/uwb/i1480/dfu/usb.c
@@ -341,6 +341,7 @@ int i1480_usb_cmd(struct i1480 *i1480, const char *cmd_name, size_t cmd_size)
static
int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
{
+ struct usb_device *udev = interface_to_usbdev(iface);
struct i1480_usb *i1480_usb;
struct i1480 *i1480;
struct device *dev = &iface->dev;
@@ -352,8 +353,8 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
iface->cur_altsetting->desc.bInterfaceNumber);
goto error;
}
- if (iface->num_altsetting > 1
- && interface_to_usbdev(iface)->descriptor.idProduct == 0xbabe) {
+ if (iface->num_altsetting > 1 &&
+ le16_to_cpu(udev->descriptor.idProduct) == 0xbabe) {
/* Need altsetting #1 [HW QUIRK] or EP1 won't work */
result = usb_set_interface(interface_to_usbdev(iface), 0, 1);
if (result < 0)
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index 748a74bd85e7..7da3298a119f 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -641,6 +641,9 @@ static int usb_pcwd_probe(struct usb_interface *interface,
return -ENODEV;
}

+ if (iface_desc->desc.bNumEndpoints < 1)
+ return -ENODEV;
+
/* check out the endpoint: it has to be Interrupt & IN */
endpoint = &iface_desc->endpoint[0].desc;

diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
index ba6eda4b5143..0d23e1f5846a 100644
--- a/drivers/xen/biomerge.c
+++ b/drivers/xen/biomerge.c
@@ -8,6 +8,5 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));

- return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
- ((mfn1 == mfn2) || ((mfn1+1) == mfn2));
+ return mfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == mfn2;
}
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 62d7a6d9a701..38a2f2c512d7 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -345,7 +345,7 @@ static int autofs_dev_ioctl_fail(struct file *fp,
int status;

token = (autofs_wqt_t) param->fail.token;
- status = param->fail.status ? param->fail.status : -ENOENT;
+ status = param->fail.status < 0 ? param->fail.status : -ENOENT;
return autofs4_wait_release(sbi, token, status);
}

diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index 0f3eb41d9201..5ffc3f698c53 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -83,14 +83,13 @@ static int create_link(struct config_item *parent_item,
ret = -ENOMEM;
sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
if (sl) {
- sl->sl_target = config_item_get(item);
spin_lock(&configfs_dirent_lock);
if (target_sd->s_type & CONFIGFS_USET_DROPPING) {
spin_unlock(&configfs_dirent_lock);
- config_item_put(item);
kfree(sl);
return -ENOENT;
}
+ sl->sl_target = config_item_get(item);
list_add(&sl->sl_list, &target_sd->s_links);
spin_unlock(&configfs_dirent_lock);
ret = configfs_create_link(sl, parent_item->ci_dentry,
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bb40a70ed412..aa54e82d74c3 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -5023,6 +5023,8 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
ext4_orphan_del(handle, inode);
inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
ext4_mark_inode_dirty(handle, inode);
+ if (err >= 0)
+ ext4_update_inode_fsync_trans(handle, inode, 1);
ext4_journal_stop(handle);
return err;
}
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index f881e3484481..fde77a79d814 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1344,7 +1344,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
int ret = 0, err, nr_pages, i;
struct inode *inode = mpd->inode;
struct address_space *mapping = inode->i_mapping;
- loff_t size = i_size_read(inode);
unsigned int len, block_start;
struct buffer_head *bh, *page_bufs = NULL;
int journal_data = ext4_should_journal_data(inode);
@@ -1370,6 +1369,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
for (i = 0; i < nr_pages; i++) {
int commit_write = 0, skip_page = 0;
struct page *page = pvec.pages[i];
+ loff_t size = i_size_read(inode);

index = page->index;
if (index > end)
@@ -1443,11 +1443,31 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
if (skip_page)
goto skip_page;

+ clear_page_dirty_for_io(page);
+ /*
+ * We have to be very careful here! Nothing protects
+ * writeback path against i_size changes and the page
+ * can be writeably mapped into page tables. So an
+ * application can be growing i_size and writing data
+ * through mmap while writeback runs.
+ * clear_page_dirty_for_io() write-protects our page in
+ * page tables and the page cannot get written to again
+ * until we release page lock. So only after
+ * clear_page_dirty_for_io() we are safe to sample
+ * i_size for ext4_bio_write_page() to zero-out tail of
+ * the written page. We rely on the barrier provided by
+ * TestClearPageDirty in clear_page_dirty_for_io() to
+ * make sure i_size is really sampled only after page
+ * tables are updated.
+ */
+ if (size != i_size_read(inode)) {
+ set_page_dirty(page);
+ goto skip_page;
+ }
+
if (commit_write)
/* mark the buffer_heads as dirty & uptodate */
block_commit_write(page, 0, len);
-
- clear_page_dirty_for_io(page);
/*
* Delalloc doesn't support data journalling,
* but eventually maybe we'll lift this
@@ -4637,8 +4657,9 @@ static int ext4_expand_extra_isize(struct inode *inode,
/* No extended attributes present */
if (!ext4_test_inode_state(inode, EXT4_STATE_XATTR) ||
header->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC)) {
- memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE, 0,
- new_extra_isize);
+ memset((void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+ EXT4_I(inode)->i_extra_isize, 0,
+ new_extra_isize - EXT4_I(inode)->i_extra_isize);
EXT4_I(inode)->i_extra_isize = new_extra_isize;
return 0;
}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 18c58e5c7260..66897c9851ab 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -457,8 +457,10 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,

if (info) {
struct partition_meta_info *pinfo = alloc_part_info(disk);
- if (!pinfo)
+ if (!pinfo) {
+ err = -ENOMEM;
goto out_free_stats;
+ }
memcpy(pinfo, info, sizeof(*info));
p->info = pinfo;
}
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 439b5a1048c9..b83dcbb83d3f 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -380,7 +380,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,

state = *get_task_state(task);
vsize = eip = esp = 0;
- permitted = ptrace_may_access(task, PTRACE_MODE_READ);
+ permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
mm = get_task_mm(task);
if (mm) {
vsize = task_vsize(mm);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 2c38a3e4fa51..9bc4643054bf 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -216,7 +216,7 @@ static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)

struct mm_struct *mm_for_maps(struct task_struct *task)
{
- return mm_access(task, PTRACE_MODE_READ);
+ return mm_access(task, PTRACE_MODE_READ_FSCREDS);
}

static int proc_pid_cmdline(struct task_struct *task, char * buffer)
@@ -288,7 +288,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
wchan = get_wchan(task);

if (lookup_symbol_name(wchan, symname) < 0)
- if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
return 0;
else
return sprintf(buffer, "%lu", wchan);
@@ -302,7 +302,7 @@ static int lock_trace(struct task_struct *task)
int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
if (err)
return err;
- if (!ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+ if (!ptrace_may_access(task, PTRACE_MODE_ATTACH_FSCREDS)) {
mutex_unlock(&task->signal->cred_guard_mutex);
return -EPERM;
}
@@ -544,7 +544,7 @@ static int proc_fd_access_allowed(struct inode *inode)
*/
task = get_proc_task(inode);
if (task) {
- allowed = ptrace_may_access(task, PTRACE_MODE_READ);
+ allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS);
put_task_struct(task);
}
return allowed;
@@ -769,7 +769,7 @@ static int mem_open(struct inode* inode, struct file* file)
if (!task)
return -ESRCH;

- mm = mm_access(task, PTRACE_MODE_ATTACH);
+ mm = mm_access(task, PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS);
put_task_struct(task);

if (IS_ERR(mm))
@@ -2627,7 +2627,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
if (result)
return result;

- if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
result = -EACCES;
goto out_unlock;
}
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index d6c078ea1489..50de28b0a670 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -91,7 +91,7 @@ static int proc_ns_dir_readdir(struct file *filp, void *dirent,
goto out_no_task;

ret = -EPERM;
- if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
goto out;

ret = 0;
@@ -154,7 +154,7 @@ static struct dentry *proc_ns_dir_lookup(struct inode *dir,
goto out_no_task;

error = ERR_PTR(-EPERM);
- if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
goto out;

last = &ns_entries[ARRAY_SIZE(ns_entries) - 1];
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 879b13436fa4..56947d3e0e68 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -890,7 +890,10 @@ void ufs_evict_inode(struct inode * inode)
ufs_update_inode(inode, IS_SYNC(inode));
old_i_size = inode->i_size;
inode->i_size = 0;
- if (inode->i_blocks && ufs_truncate(inode, old_i_size))
+ if (inode->i_blocks &&
+ (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+ S_ISLNK(inode->i_mode)) &&
+ ufs_truncate(inode, old_i_size))
ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
unlock_ufs(inode->i_sb);
}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 3915ade6f9a8..c7090f5b24b6 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -695,6 +695,23 @@ static void ufs_put_super_internal(struct super_block *sb)
UFSD("EXIT\n");
}

+static u64 ufs_max_bytes(struct super_block *sb)
+{
+ struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
+ int bits = uspi->s_apbshift;
+ u64 res;
+
+ if (bits > 21)
+ res = ~0ULL;
+ else
+ res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) +
+ (1LL << (3*bits));
+
+ if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift))
+ return MAX_LFS_FILESIZE;
+ return res << uspi->s_bshift;
+}
+
static int ufs_fill_super(struct super_block *sb, void *data, int silent)
{
struct ufs_sb_info * sbi;
@@ -1157,6 +1174,7 @@ again:
"fast symlink size (%u)\n", uspi->s_maxsymlinklen);
uspi->s_maxsymlinklen = maxsymlen;
}
+ sb->s_maxbytes = ufs_max_bytes(sb);

inode = ufs_iget(sb, UFS_ROOTINO);
if (IS_ERR(inode)) {
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 92cde998aead..93bc59c0d598 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -451,12 +451,6 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size)
inode->i_ino, (unsigned long long)i_size_read(inode),
(unsigned long long)old_i_size);

- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return -EINVAL;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- return -EPERM;
-
err = ufs_alloc_lastblock(inode);

if (err) {
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 954175928240..3f9463f8cf2f 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -473,15 +473,19 @@ static inline unsigned _ubh_find_last_zero_bit_(
static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi,
struct ufs_buffer_head * ubh, unsigned begin, unsigned block)
{
+ u8 mask;
switch (uspi->s_fpb) {
case 8:
return (*ubh_get_addr (ubh, begin + block) == 0xff);
case 4:
- return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2)));
+ mask = 0x0f << ((block & 0x01) << 2);
+ return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask;
case 2:
- return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1)));
+ mask = 0x03 << ((block & 0x03) << 1);
+ return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask;
case 1:
- return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07)));
+ mask = 0x01 << (block & 0x07);
+ return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask;
}
return 0;
}
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index dce6e4dbeda7..8e44d7305fef 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -292,7 +292,9 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table,
int write, void __user *buffer,
size_t *length, loff_t *ppos);
#endif
-
+extern void wait_for_kprobe_optimizer(void);
+#else
+static inline void wait_for_kprobe_optimizer(void) { }
#endif /* CONFIG_OPTPROBES */

/* Get the kprobe at this addr (if any) - called with preemption disabled */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index e49240ba8346..953193651aa8 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -130,9 +130,31 @@ extern void __ptrace_unlink(struct task_struct *child);
extern void exit_ptrace(struct task_struct *tracer);
#define PTRACE_MODE_READ 1
#define PTRACE_MODE_ATTACH 2
+#define PTRACE_MODE_FSCREDS 0x08
+#define PTRACE_MODE_REALCREDS 0x10
+
+/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */
+#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS)
+#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS)
+#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS)
+
/* Returns 0 on success, -errno on denial. */
extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
-/* Returns true on success, false on denial. */
+/**
+ * ptrace_may_access - check whether the caller is permitted to access
+ * a target task.
+ * @task: target task
+ * @mode: selects type of access and caller credentials
+ *
+ * Returns true on success, false on denial.
+ *
+ * One of the flags PTRACE_MODE_FSCREDS and PTRACE_MODE_REALCREDS must
+ * be set in @mode to specify whether the access was requested through
+ * a filesystem syscall (should use effective capabilities and fsuid
+ * of the caller) or through an explicit syscall such as
+ * process_vm_writev or ptrace (and should use the real credentials).
+ */
extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);

static inline int ptrace_reparented(struct task_struct *child)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2af31eb76bd0..42e067bb16c8 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -534,6 +534,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
}

extern void kfree_skb(struct sk_buff *skb);
+extern void kfree_skb_list(struct sk_buff *segs);
extern void consume_skb(struct sk_buff *skb);
extern void __kfree_skb(struct sk_buff *skb);
extern struct sk_buff *__alloc_skb(unsigned int size,
diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
index 1eb735b53fc4..5c62734112d9 100644
--- a/include/linux/usb/ch11.h
+++ b/include/linux/usb/ch11.h
@@ -11,6 +11,9 @@

#include <linux/types.h> /* __u8 etc */

+/* See USB 3.1 spec Table 10-5 */
+#define USB_SS_MAXPORTS 15
+
/*
* Hub request types
*/
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 921f6270a20c..9e5f33784ea1 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -925,10 +925,6 @@ struct xfrm_dst {
struct flow_cache_object flo;
struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
int num_pols, num_xfrms;
-#ifdef CONFIG_XFRM_SUB_POLICY
- struct flowi *origin;
- struct xfrm_selector *partner;
-#endif
u32 xfrm_genid;
u32 policy_genid;
u32 route_mtu_cached;
@@ -944,12 +940,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
dst_release(xdst->route);
if (likely(xdst->u.dst.xfrm))
xfrm_state_put(xdst->u.dst.xfrm);
-#ifdef CONFIG_XFRM_SUB_POLICY
- kfree(xdst->origin);
- xdst->origin = NULL;
- kfree(xdst->partner);
- xdst->partner = NULL;
-#endif
}
#endif

diff --git a/kernel/events/core.c b/kernel/events/core.c
index cd4f88a39fe1..bc94278e0b45 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3004,7 +3004,7 @@ find_lively_task_by_vpid(pid_t vpid)

/* Reuse ptrace permission checks for now. */
err = -EACCES;
- if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
goto errout;

return task;
diff --git a/kernel/futex.c b/kernel/futex.c
index bbd360110079..3854e754f641 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -2627,7 +2627,7 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
}

ret = -EPERM;
- if (!ptrace_may_access(p, PTRACE_MODE_READ))
+ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
goto err_unlock;

head = p->robust_list;
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index a9642d528630..e07b64b465fc 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -154,7 +154,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
}

ret = -EPERM;
- if (!ptrace_may_access(p, PTRACE_MODE_READ))
+ if (!ptrace_may_access(p, PTRACE_MODE_READ_REALCREDS))
goto err_unlock;

head = p->compat_robust_list;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index bc90b875f63a..a4f561a3f27f 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -598,7 +598,7 @@ static __kprobes void kprobe_optimizer(struct work_struct *work)
}

/* Wait for completing optimization and unoptimization */
-static __kprobes void wait_for_kprobe_optimizer(void)
+__kprobes void wait_for_kprobe_optimizer(void)
{
if (delayed_work_pending(&optimizing_work))
wait_for_completion(&optimizer_comp);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index fd3909b87188..b50cded5b80e 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -220,6 +220,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state)
int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
const struct cred *cred = current_cred(), *tcred;
+ int dumpable = 0;
+ uid_t caller_uid;
+ gid_t caller_gid;
+
+ if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) {
+ WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
+ return -EPERM;
+ }

/* May we inspect the given task?
* This check is used both for attaching with ptrace
@@ -229,19 +237,34 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
* because setting up the necessary parent/child relationship
* or halting the specified task is impossible.
*/
- int dumpable = 0;
+
/* Don't let security modules deny introspection */
if (same_thread_group(task, current))
return 0;
rcu_read_lock();
+ if (mode & PTRACE_MODE_FSCREDS) {
+ caller_uid = cred->fsuid;
+ caller_gid = cred->fsgid;
+ } else {
+ /*
+ * Using the euid would make more sense here, but something
+ * in userland might rely on the old behavior, and this
+ * shouldn't be a security problem since
+ * PTRACE_MODE_REALCREDS implies that the caller explicitly
+ * used a syscall that requests access to another process
+ * (and not a filesystem syscall to procfs).
+ */
+ caller_uid = cred->uid;
+ caller_gid = cred->gid;
+ }
tcred = __task_cred(task);
if (cred->user->user_ns == tcred->user->user_ns &&
- (cred->uid == tcred->euid &&
- cred->uid == tcred->suid &&
- cred->uid == tcred->uid &&
- cred->gid == tcred->egid &&
- cred->gid == tcred->sgid &&
- cred->gid == tcred->gid))
+ (caller_uid == tcred->euid &&
+ caller_uid == tcred->suid &&
+ caller_uid == tcred->uid &&
+ caller_gid == tcred->egid &&
+ caller_gid == tcred->sgid &&
+ caller_gid == tcred->gid))
goto ok;
if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
goto ok;
@@ -308,7 +331,7 @@ static int ptrace_attach(struct task_struct *task, long request,
goto out;

task_lock(task);
- retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
+ retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
task_unlock(task);
if (retval)
goto unlock_creds;
diff --git a/kernel/signal.c b/kernel/signal.c
index 3ecf57489376..0b864fc208e4 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -535,7 +535,8 @@ unblock_all_signals(void)
spin_unlock_irqrestore(&current->sighand->siglock, flags);
}

-static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
+static void collect_signal(int sig, struct sigpending *list, siginfo_t *info,
+ bool *resched_timer)
{
struct sigqueue *q, *first = NULL;

@@ -557,6 +558,12 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
still_pending:
list_del_init(&first->list);
copy_siginfo(info, &first->info);
+
+ *resched_timer =
+ (first->flags & SIGQUEUE_PREALLOC) &&
+ (info->si_code == SI_TIMER) &&
+ (info->si_sys_private);
+
__sigqueue_free(first);
} else {
/*
@@ -573,7 +580,7 @@ static void collect_signal(int sig, struct sigpending *list, siginfo_t *info)
}

static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
- siginfo_t *info)
+ siginfo_t *info, bool *resched_timer)
{
int sig = next_signal(pending, mask);

@@ -587,7 +594,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
}
}

- collect_signal(sig, pending, info);
+ collect_signal(sig, pending, info, resched_timer);
}

return sig;
@@ -601,15 +608,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
*/
int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
{
+ bool resched_timer = false;
int signr;

/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
- signr = __dequeue_signal(&tsk->pending, mask, info);
+ signr = __dequeue_signal(&tsk->pending, mask, info, &resched_timer);
if (!signr) {
signr = __dequeue_signal(&tsk->signal->shared_pending,
- mask, info);
+ mask, info, &resched_timer);
/*
* itimer signal ?
*
@@ -654,7 +662,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
*/
current->jobctl |= JOBCTL_STOP_DEQUEUED;
}
- if ((info->si_code & __SI_MASK) == __SI_TIMER && info->si_sys_private) {
+ if (resched_timer) {
/*
* Release the siglock to ensure proper locking order
* of timer locks outside of siglocks. Note, we leave
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 7eaf1627803b..c82900ceb599 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -419,7 +419,7 @@ u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval)
overrun++;
}

- alarm->node.expires = ktime_add(alarm->node.expires, interval);
+ alarm->node.expires = ktime_add_safe(alarm->node.expires, interval);
return overrun;
}

@@ -598,13 +598,21 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,

/* start the timer */
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval);
+
+ /*
+ * Rate limit to the tick as a hot fix to prevent DOS. Will be
+ * mopped up later.
+ */
+ if (ktime_to_ns(timr->it.alarm.interval) < TICK_NSEC)
+ timr->it.alarm.interval = ktime_set(1, 0);
+
exp = timespec_to_ktime(new_setting->it_value);
/* Convert (if necessary) to absolute time */
if (flags != TIMER_ABSTIME) {
ktime_t now;

now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
- exp = ktime_add(now, exp);
+ exp = ktime_add_safe(now, exp);
}

alarm_start(&timr->it.alarm.alarmtimer, exp);
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 00d527c945a4..2ec1a389a939 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1225,24 +1225,21 @@ static int create_trace_probe(int argc, char **argv)
pr_info("Probe point is not specified.\n");
return -EINVAL;
}
- if (isdigit(argv[1][0])) {
+
+ /* try to parse an address. if that fails, try to read the
+ * input as a symbol. */
+ if (!strict_strtoul(argv[1], 0, (unsigned long *)&addr)) {
if (is_return) {
pr_info("Return probe point must be a symbol.\n");
return -EINVAL;
}
- /* an address specified */
- ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr);
- if (ret) {
- pr_info("Failed to parse address.\n");
- return ret;
- }
} else {
/* a symbol specified */
symbol = argv[1];
/* TODO: support .init module functions */
ret = split_symbol_offset(symbol, &offset);
if (ret) {
- pr_info("Failed to parse symbol.\n");
+ pr_info("Failed to parse either an address or a symbol.\n");
return ret;
}
if (offset && is_return) {
@@ -2109,6 +2106,11 @@ static __init int kprobe_trace_self_tests_init(void)

end:
release_all_trace_probes();
+ /*
+ * Wait for the optimizer work to finish. Otherwise it might fiddle
+ * with probes in already freed __init text.
+ */
+ wait_for_kprobe_optimizer();
if (warn)
pr_cont("NG: Some tests are failed. Please check them.\n");
else
diff --git a/lib/cmdline.c b/lib/cmdline.c
index f5f3ad8b62ff..82c466facfe0 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -22,14 +22,14 @@
* the values[M, M+1, ..., N] into the ints array in get_options.
*/

-static int get_range(char **str, int *pint)
+static int get_range(char **str, int *pint, int n)
{
int x, inc_counter, upper_range;

(*str)++;
upper_range = simple_strtol((*str), NULL, 0);
inc_counter = upper_range - *pint;
- for (x = *pint; x < upper_range; x++)
+ for (x = *pint; n && x < upper_range; x++, n--)
*pint++ = x;
return inc_counter;
}
@@ -95,7 +95,7 @@ char *get_options(const char *str, int nints, int *ints)
break;
if (res == 3) {
int range_nums;
- range_nums = get_range((char **)&str, ints + i);
+ range_nums = get_range((char **)&str, ints + i, nints - i);
if (range_nums < 0)
break;
/*
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index c55593549cc9..c8e4ebe5f78d 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1334,12 +1334,9 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
err = -ESRCH;
goto out;
}
- mm = get_task_mm(task);
- rcu_read_unlock();
+ get_task_struct(task);

err = -EINVAL;
- if (!mm)
- goto out;

/*
* Check if this process has the right to modify the specified
@@ -1347,14 +1344,13 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
* capabilities, superuser privileges or the same
* userid as the target process.
*/
- rcu_read_lock();
tcred = __task_cred(task);
if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
cred->uid != tcred->suid && cred->uid != tcred->uid &&
!capable(CAP_SYS_NICE)) {
rcu_read_unlock();
err = -EPERM;
- goto out;
+ goto out_put;
}
rcu_read_unlock();

@@ -1362,26 +1358,39 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode,
/* Is the user allowed to access the target nodes? */
if (!nodes_subset(*new, task_nodes) && !capable(CAP_SYS_NICE)) {
err = -EPERM;
- goto out;
+ goto out_put;
}

if (!nodes_subset(*new, node_states[N_HIGH_MEMORY])) {
err = -EINVAL;
- goto out;
+ goto out_put;
}

err = security_task_movememory(task);
if (err)
+ goto out_put;
+
+ mm = get_task_mm(task);
+ put_task_struct(task);
+
+ if (!mm) {
+ err = -EINVAL;
goto out;
+ }

err = do_migrate_pages(mm, old, new,
capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
+
+ mmput(mm);
out:
- if (mm)
- mmput(mm);
NODEMASK_SCRATCH_FREE(scratch);

return err;
+
+out_put:
+ put_task_struct(task);
+ goto out;
+
}


diff --git a/mm/migrate.c b/mm/migrate.c
index f2d86f2bd203..3f95bab563cb 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -34,6 +34,7 @@
#include <linux/syscalls.h>
#include <linux/hugetlb.h>
#include <linux/gfp.h>
+#include <linux/ptrace.h>

#include <asm/tlbflush.h>

@@ -1198,20 +1199,17 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
* Migrate an array of page address onto an array of nodes and fill
* the corresponding array of status.
*/
-static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
unsigned long nr_pages,
const void __user * __user *pages,
const int __user *nodes,
int __user *status, int flags)
{
struct page_to_node *pm;
- nodemask_t task_nodes;
unsigned long chunk_nr_pages;
unsigned long chunk_start;
int err;

- task_nodes = cpuset_mems_allowed(task);
-
err = -ENOMEM;
pm = (struct page_to_node *)__get_free_page(GFP_KERNEL);
if (!pm)
@@ -1369,10 +1367,10 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
const int __user *, nodes,
int __user *, status, int, flags)
{
- const struct cred *cred = current_cred(), *tcred;
struct task_struct *task;
struct mm_struct *mm;
int err;
+ nodemask_t task_nodes;

/* Check flags */
if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
@@ -1388,23 +1386,13 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
rcu_read_unlock();
return -ESRCH;
}
- mm = get_task_mm(task);
- rcu_read_unlock();
-
- if (!mm)
- return -EINVAL;
+ get_task_struct(task);

/*
* Check if this process has the right to modify the specified
- * process. The right exists if the process has administrative
- * capabilities, superuser privileges or the same
- * userid as the target process.
+ * process. Use the regular "ptrace_may_access()" checks.
*/
- rcu_read_lock();
- tcred = __task_cred(task);
- if (cred->euid != tcred->suid && cred->euid != tcred->uid &&
- cred->uid != tcred->suid && cred->uid != tcred->uid &&
- !capable(CAP_SYS_NICE)) {
+ if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS)) {
rcu_read_unlock();
err = -EPERM;
goto out;
@@ -1415,16 +1403,25 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
if (err)
goto out;

- if (nodes) {
- err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
- flags);
- } else {
+ task_nodes = cpuset_mems_allowed(task);
+ mm = get_task_mm(task);
+ put_task_struct(task);
+
+ if (!mm)
+ return -EINVAL;
+
+ if (nodes)
+ err = do_pages_move(mm, task_nodes, nr_pages, pages,
+ nodes, status, flags);
+ else
err = do_pages_stat(mm, nr_pages, pages, status);
- }

-out:
mmput(mm);
return err;
+
+out:
+ put_task_struct(task);
+ return err;
}

/*
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
index 6f4ef535c5af..c7a7e01fffc9 100644
--- a/mm/page_cgroup.c
+++ b/mm/page_cgroup.c
@@ -399,6 +399,9 @@ static int swap_cgroup_prepare(int type)
if (!page)
goto not_enough_page;
ctrl->map[idx] = page;
+
+ if (!(idx % SWAP_CLUSTER_MAX))
+ cond_resched();
}
return 0;
not_enough_page:
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 70e814a4d0b8..88c35c9e4407 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -299,7 +299,7 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
}

task_lock(task);
- if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
+ if (__ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS)) {
task_unlock(task);
rc = -EPERM;
goto put_task_struct;
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index bb38a3c51912..e31529d9d121 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -268,6 +268,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
u32 yes;
struct crush_rule *r;

+ err = -EINVAL;
ceph_decode_32_safe(p, end, yes, bad);
if (!yes) {
dout("crush_decode NO rule %d off %x %p to %p\n",
diff --git a/net/core/dev.c b/net/core/dev.c
index 164958d192a3..bb7a0cc037e9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5942,7 +5942,7 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev,
} else {
netdev_stats_to_stats64(storage, &dev->stats);
}
- storage->rx_dropped += atomic_long_read(&dev->rx_dropped);
+ storage->rx_dropped += (unsigned long)atomic_long_read(&dev->rx_dropped);
return storage;
}
EXPORT_SYMBOL(dev_get_stats);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 684b57380b2b..f2007b3d4177 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -791,6 +791,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ nla_total_size(4) /* IFLA_MASTER */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
+ + nla_total_size(4) /* IFLA_GROUP */
+ nla_total_size(ext_filter_mask
& RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
+ rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
@@ -1142,6 +1143,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
[IFLA_EXT_MASK] = { .type = NLA_U32 },
+ [IFLA_GROUP] = { .type = NLA_U32 },
};
EXPORT_SYMBOL(ifla_policy);

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b30d9c2fd5bd..847b314b3a70 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -277,15 +277,8 @@ EXPORT_SYMBOL(dev_alloc_skb);

static void skb_drop_list(struct sk_buff **listp)
{
- struct sk_buff *list = *listp;
-
+ kfree_skb_list(*listp);
*listp = NULL;
-
- do {
- struct sk_buff *this = list;
- list = list->next;
- kfree_skb(this);
- } while (list);
}

static inline void skb_drop_fraglist(struct sk_buff *skb)
@@ -436,6 +429,17 @@ void kfree_skb(struct sk_buff *skb)
}
EXPORT_SYMBOL(kfree_skb);

+void kfree_skb_list(struct sk_buff *segs)
+{
+ while (segs) {
+ struct sk_buff *next = segs->next;
+
+ kfree_skb(segs);
+ segs = next;
+ }
+}
+EXPORT_SYMBOL(kfree_skb_list);
+
/**
* consume_skb - free an skbuff
* @skb: buffer to free
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index e2ab9681f53a..19dcfe518cd1 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1032,7 +1032,7 @@ static struct inet_protosw inetsw_array[] =
.type = SOCK_DGRAM,
.protocol = IPPROTO_ICMP,
.prot = &ping_prot,
- .ops = &inet_dgram_ops,
+ .ops = &inet_sockraw_ops,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
},
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 80a9a9710726..9d0a94bfe5dc 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2106,6 +2106,10 @@ int tcp_disconnect(struct sock *sk, int flags)
tcp_set_ca_state(sk, TCP_CA_Open);
tcp_clear_retrans(tp);
inet_csk_delack_init(sk);
+ /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
+ * issue in __tcp_select_window()
+ */
+ icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
tcp_init_send_head(sk);
memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
__sk_dst_reset(sk);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index eb7a8fba6f4f..73a4355c7431 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1303,13 +1303,14 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
*/
if (pkt_len > mss) {
unsigned int new_len = (pkt_len / mss) * mss;
- if (!in_sack && new_len < pkt_len) {
+ if (!in_sack && new_len < pkt_len)
new_len += mss;
- if (new_len >= skb->len)
- return 0;
- }
pkt_len = new_len;
}
+
+ if (pkt_len >= skb->len && !in_sack)
+ return 0;
+
err = tcp_fragment(sk, skb, pkt_len, mss);
if (err < 0)
return err;
@@ -3424,7 +3425,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
int delta;

/* Non-retransmitted hole got filled? That's reordering */
- if (reord < prior_fackets)
+ if (reord < prior_fackets && reord <= tp->fackets_out)
tcp_update_reordering(sk, tp->fackets_out - reord, 0);

delta = tcp_is_fack(tp) ? pkts_acked :
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9a851d16beda..cb1de47d8c2c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2633,6 +2633,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = (struct net_device *) data;
struct inet6_dev *idev = __in6_dev_get(dev);
+ struct net *net = dev_net(dev);
int run_pending = 0;
int err;

@@ -2733,7 +2734,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
* IPV6_MIN_MTU stop IPv6 on this interface.
*/
if (dev->mtu < IPV6_MIN_MTU)
- addrconf_ifdown(dev, 1);
+ addrconf_ifdown(dev, dev != net->loopback_dev);
}
break;

@@ -2754,6 +2755,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
* MTU falled under IPV6_MIN_MTU.
* Stop IPv6 on this interface.
*/
+ addrconf_ifdown(dev, dev != net->loopback_dev);
+ break;

case NETDEV_DOWN:
case NETDEV_UNREGISTER:
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index b0e4fb8ef93d..70390686633d 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -824,8 +824,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, u32 features)
sizeof(*ipv6h));
if (proto == IPPROTO_UDP) {
int err = ip6_find_1stfragopt(skb, &prevhdr);
- if (err < 0)
+ if (err < 0) {
+ kfree_skb_list(segs);
return ERR_PTR(err);
+ }
fptr = (struct frag_hdr *)(skb_network_header(skb) +
err);
fptr->frag_off = htons(offset);
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c
index 63d5d493098a..bc75be1ea310 100644
--- a/net/ipv6/xfrm6_mode_ro.c
+++ b/net/ipv6/xfrm6_mode_ro.c
@@ -48,6 +48,8 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
iph = ipv6_hdr(skb);

hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+ if (hdr_len < 0)
+ return hdr_len;
skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
skb_set_network_header(skb, -x->props.header_len);
skb->transport_header = skb->network_header + hdr_len;
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c
index 4e344105b3fd..1d3bbe6e1183 100644
--- a/net/ipv6/xfrm6_mode_transport.c
+++ b/net/ipv6/xfrm6_mode_transport.c
@@ -28,6 +28,8 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
iph = ipv6_hdr(skb);

hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+ if (hdr_len < 0)
+ return hdr_len;
skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
skb_set_network_header(skb, -x->props.header_len);
skb->transport_header = skb->network_header + hdr_len;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 1b19d6a4646f..35fc5ba2826b 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1152,6 +1152,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
goto out;
}

+ err = -ENOBUFS;
key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
if (sa->sadb_sa_auth) {
int keysize = 0;
@@ -1163,8 +1164,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
if (key)
keysize = (key->sadb_key_bits + 7) / 8;
x->aalg = kmalloc(sizeof(*x->aalg) + keysize, GFP_KERNEL);
- if (!x->aalg)
+ if (!x->aalg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->aalg->alg_name, a->name);
x->aalg->alg_key_len = 0;
if (key) {
@@ -1183,8 +1186,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
goto out;
}
x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL);
- if (!x->calg)
+ if (!x->calg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->calg->alg_name, a->name);
x->props.calgo = sa->sadb_sa_encrypt;
} else {
@@ -1198,8 +1203,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
if (key)
keysize = (key->sadb_key_bits + 7) / 8;
x->ealg = kmalloc(sizeof(*x->ealg) + keysize, GFP_KERNEL);
- if (!x->ealg)
+ if (!x->ealg) {
+ err = -ENOMEM;
goto out;
+ }
strcpy(x->ealg->alg_name, a->name);
x->ealg->alg_key_len = 0;
if (key) {
@@ -1247,8 +1254,10 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
struct xfrm_encap_tmpl *natt;

x->encap = kmalloc(sizeof(*x->encap), GFP_KERNEL);
- if (!x->encap)
+ if (!x->encap) {
+ err = -ENOMEM;
goto out;
+ }

natt = x->encap;
n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
@@ -3230,7 +3239,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
p += pol->sadb_x_policy_len*8;
sec_ctx = (struct sadb_x_sec_ctx *)p;
if (len < pol->sadb_x_policy_len*8 +
- sec_ctx->sadb_x_sec_len) {
+ sec_ctx->sadb_x_sec_len*8) {
*dir = -EINVAL;
goto out;
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 96c34c15b1ea..0cfb95a37540 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1959,7 +1959,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(hdr->addr1)) {
mpp_addr = hdr->addr3;
proxied_addr = mesh_hdr->eaddr1;
- } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
+ } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
+ MESH_FLAGS_AE_A5_A6) {
/* has_a4 already checked in ieee80211_rx_mesh_check */
mpp_addr = hdr->addr4;
proxied_addr = mesh_hdr->eaddr2;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 73db20f1277a..93bb8ae74537 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -731,8 +731,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
}
out:
spin_unlock_bh(&nf_conntrack_lock);
- if (last)
+ if (last) {
+ /* nf ct hash resize happened, now clear the leftover. */
+ if ((struct nf_conn *)cb->args[1] == last)
+ cb->args[1] = 0;
+
nf_ct_put(last);
+ }

return skb->len;
}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5fba039ca6dd..870c52dcd384 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -360,12 +360,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
+ u8 mesh_flags;
+
/* make sure meshdr->flags is on the linear part */
if (!pskb_may_pull(skb, hdrlen + 1))
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A4)
+ mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+ if (mesh_flags == MESH_FLAGS_AE_A4)
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+ if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
skb_copy_bits(skb, hdrlen +
offsetof(struct ieee80211s_hdr, eaddr1),
dst, ETH_ALEN);
@@ -386,12 +389,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
+ u8 mesh_flags;
+
/* make sure meshdr->flags is on the linear part */
if (!pskb_may_pull(skb, hdrlen + 1))
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
+ mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+ if (mesh_flags == MESH_FLAGS_AE_A5_A6)
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A4)
+ if (mesh_flags == MESH_FLAGS_AE_A4)
skb_copy_bits(skb, hdrlen +
offsetof(struct ieee80211s_hdr, eaddr1),
src, ETH_ALEN);
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 113d20ef31a4..3ca14dc2ab96 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1530,41 +1530,6 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
goto out;
}

-static int inline
-xfrm_dst_alloc_copy(void **target, const void *src, int size)
-{
- if (!*target) {
- *target = kmalloc(size, GFP_ATOMIC);
- if (!*target)
- return -ENOMEM;
- }
- memcpy(*target, src, size);
- return 0;
-}
-
-static int inline
-xfrm_dst_update_parent(struct dst_entry *dst, const struct xfrm_selector *sel)
-{
-#ifdef CONFIG_XFRM_SUB_POLICY
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
- return xfrm_dst_alloc_copy((void **)&(xdst->partner),
- sel, sizeof(*sel));
-#else
- return 0;
-#endif
-}
-
-static int inline
-xfrm_dst_update_origin(struct dst_entry *dst, const struct flowi *fl)
-{
-#ifdef CONFIG_XFRM_SUB_POLICY
- struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
- return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl));
-#else
- return 0;
-#endif
-}
-
static int xfrm_expand_policies(const struct flowi *fl, u16 family,
struct xfrm_policy **pols,
int *num_pols, int *num_xfrms)
@@ -1636,16 +1601,6 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,

xdst = (struct xfrm_dst *)dst;
xdst->num_xfrms = err;
- if (num_pols > 1)
- err = xfrm_dst_update_parent(dst, &pols[1]->selector);
- else
- err = xfrm_dst_update_origin(dst, fl);
- if (unlikely(err)) {
- dst_free(dst);
- XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
- return ERR_PTR(err);
- }
-
xdst->num_pols = num_pols;
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
xdst->policy_genid = atomic_read(&pols[0]->genid);
@@ -2942,9 +2897,15 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_state *x_new[XFRM_MAX_DEPTH];
struct xfrm_migrate *mp;

+ /* Stage 0 - sanity checks */
if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
goto out;

+ if (dir >= XFRM_POLICY_MAX) {
+ err = -EINVAL;
+ goto out;
+ }
+
/* Stage 1 - find policy */
if ((pol = xfrm_migrate_policy_find(sel, dir, type)) == NULL) {
err = -ENOENT;
diff --git a/security/commoncap.c b/security/commoncap.c
index 12440ee03c31..4f338aba1ddb 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -141,12 +141,17 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
int ret = 0;
const struct cred *cred, *child_cred;
+ const kernel_cap_t *caller_caps;

rcu_read_lock();
cred = current_cred();
child_cred = __task_cred(child);
+ if (mode & PTRACE_MODE_FSCREDS)
+ caller_caps = &cred->cap_effective;
+ else
+ caller_caps = &cred->cap_permitted;
if (cred->user->user_ns == child_cred->user->user_ns &&
- cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
+ cap_issubset(child_cred->cap_permitted, *caller_caps))
goto out;
if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE))
goto out;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index b9073ebd0817..41525338aa8d 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -85,7 +85,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
payload = NULL;

vm = false;
- if (_payload) {
+ if (plen) {
ret = -ENOMEM;
payload = kmalloc(plen, GFP_KERNEL);
if (!payload) {
@@ -319,7 +319,7 @@ long keyctl_update_key(key_serial_t id,

/* pull the payload in if one was supplied */
payload = NULL;
- if (_payload) {
+ if (plen) {
ret = -ENOMEM;
payload = kmalloc(plen, GFP_KERNEL);
if (!payload)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c279f2f3372d..4c6a34700d49 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -911,10 +911,8 @@ static int selinux_parse_opts_str(char *options,
goto out_err;

opts->mnt_opts_flags = kcalloc(NUM_SEL_MNT_OPTS, sizeof(int), GFP_ATOMIC);
- if (!opts->mnt_opts_flags) {
- kfree(opts->mnt_opts);
+ if (!opts->mnt_opts_flags)
goto out_err;
- }

if (fscontext) {
opts->mnt_opts[num_mnt_opts] = fscontext;
@@ -937,6 +935,7 @@ static int selinux_parse_opts_str(char *options,
return 0;

out_err:
+ security_free_mnt_opts(opts);
kfree(context);
kfree(defcontext);
kfree(fscontext);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9b89822460f3..e6f93b934ec5 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1448,6 +1448,8 @@ static const struct snd_pci_quirk stac9200_cfg_tbl[] = {
"Dell Inspiron 1501", STAC_9200_DELL_M26),
SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6,
"unknown Dell", STAC_9200_DELL_M26),
+ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0201,
+ "Dell Latitude D430", STAC_9200_DELL_M22),
/* Panasonic */
SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC),
/* Gateway machines needs EAPD to be set on resume */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a25fa63ce9a2..ff8dd8b44de4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1574,6 +1574,9 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
flush_delayed_work_sync(&rtd->delayed_work);
}

+ /* free the ALSA card at first; this syncs with pending operations */
+ snd_card_free(card->snd_card);
+
/* remove auxiliary devices */
for (i = 0; i < card->num_aux_devs; i++)
soc_remove_aux_dev(card, i);
@@ -1590,9 +1593,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
snd_soc_dapm_free(&card->dapm);

kfree(card->rtd);
- snd_card_free(card->snd_card);
return 0;
-
}

/* removes a socdev */
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 2780d9ce48bf..df1254839abe 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -170,9 +170,13 @@ EXAMPLES
or
./perf probe --add='schedule:12 cpu'

- this will add one or more probes which has the name start with "schedule".
+Add one or more probes which has the name start with "schedule".

- Add probes on lines in schedule() function which calls update_rq_clock().
+ ./perf probe schedule*
+ or
+ ./perf probe --add='schedule*'
+
+Add probes on lines in schedule() function which calls update_rq_clock().

./perf probe 'schedule;update_rq_clock*'
or
diff --git a/tools/perf/Documentation/perf-script-perl.txt b/tools/perf/Documentation/perf-script-perl.txt
index 3152cca15501..2bdf2b6aab3a 100644
--- a/tools/perf/Documentation/perf-script-perl.txt
+++ b/tools/perf/Documentation/perf-script-perl.txt
@@ -39,7 +39,7 @@ EVENT HANDLERS
When perf script is invoked using a trace script, a user-defined
'handler function' is called for each event in the trace. If there's
no handler function defined for a given event type, the event is
-ignored (or passed to a 'trace_handled' function, see below) and the
+ignored (or passed to a 'trace_unhandled' function, see below) and the
next event is processed.

Most of the event's field values are passed as arguments to the
diff --git a/tools/perf/Documentation/perf-script-python.txt b/tools/perf/Documentation/perf-script-python.txt
index 471022069119..282b0e23965e 100644
--- a/tools/perf/Documentation/perf-script-python.txt
+++ b/tools/perf/Documentation/perf-script-python.txt
@@ -149,10 +149,8 @@ def raw_syscalls__sys_enter(event_name, context, common_cpu,
print "id=%d, args=%s\n" % \
(id, args),

-def trace_unhandled(event_name, context, common_cpu, common_secs, common_nsecs,
- common_pid, common_comm):
- print_header(event_name, common_cpu, common_secs, common_nsecs,
- common_pid, common_comm)
+def trace_unhandled(event_name, context, event_fields_dict):
+ print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])

def print_header(event_name, cpu, secs, nsecs, pid, comm):
print "%-20s %5u %05u.%09u %8u %-20s " % \
@@ -321,7 +319,7 @@ So those are the essential steps in writing and running a script. The
process can be generalized to any tracepoint or set of tracepoints
you're interested in - basically find the tracepoint(s) you're
interested in by looking at the list of available events shown by
-'perf list' and/or look in /sys/kernel/debug/tracing events for
+'perf list' and/or look in /sys/kernel/debug/tracing/events/ for
detailed event and field info, record the corresponding trace data
using 'perf record', passing it the list of interesting events,
generate a skeleton script using 'perf script -g python' and modify the
@@ -334,7 +332,7 @@ right place, you can have your script listed alongside the other
scripts listed by the 'perf script -l' command e.g.:

----
-root@tropicana:~# perf script -l
+# perf script -l
List of available trace scripts:
workqueue-stats workqueue stats (ins/exe/create/destroy)
wakeup-latency system-wide min/max/avg wakeup latency
@@ -384,8 +382,6 @@ to be located in the perf/scripts/python directory in the kernel

----
# ls -al kernel-source/tools/perf/scripts/python
-
-root@tropicana:/home/trz/src/tip# ls -al tools/perf/scripts/python
total 32
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:30 .
drwxr-xr-x 4 trz trz 4096 2010-01-26 22:29 ..
@@ -400,7 +396,7 @@ otherwise your script won't show up at run-time), 'perf script -l'
should show a new entry for your script:

----
-root@tropicana:~# perf script -l
+# perf script -l
List of available trace scripts:
workqueue-stats workqueue stats (ins/exe/create/destroy)
wakeup-latency system-wide min/max/avg wakeup latency
@@ -439,7 +435,7 @@ EVENT HANDLERS
When perf script is invoked using a trace script, a user-defined
'handler function' is called for each event in the trace. If there's
no handler function defined for a given event type, the event is
-ignored (or passed to a 'trace_handled' function, see below) and the
+ignored (or passed to a 'trace_unhandled' function, see below) and the
next event is processed.

Most of the event's field values are passed as arguments to the
@@ -534,7 +530,7 @@ Aside from the event handler functions discussed above, every script
gives scripts a chance to do setup tasks:

----
-def trace_begin:
+def trace_begin():
pass
----

@@ -543,7 +539,7 @@ Aside from the event handler functions discussed above, every script
as display results:

----
-def trace_end:
+def trace_end():
pass
----

@@ -552,8 +548,7 @@ Aside from the event handler functions discussed above, every script
of common arguments are passed into it:

----
-def trace_unhandled(event_name, context, common_cpu, common_secs,
- common_nsecs, common_pid, common_comm):
+def trace_unhandled(event_name, context, event_fields_dict):
pass
----

diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 6ccf70e8d8f2..8173636c9817 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -465,7 +465,7 @@ static int python_generate_script(const char *outfile)
fprintf(ofp, "# be retrieved using Python functions of the form "
"common_*(context).\n");

- fprintf(ofp, "# See the perf-trace-python Documentation for the list "
+ fprintf(ofp, "# See the perf-script-python Documentation for the list "
"of available functions.\n\n");

fprintf(ofp, "import os\n");

Attachment: signature.asc
Description: This is a digitally signed message part