Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 May 2014 15:32:48 +0000 (08:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 3 May 2014 15:32:48 +0000 (08:32 -0700)
Pull irq fixes from Thomas Gleixner:
 "This udpate delivers:

   - A fix for dynamic interrupt allocation on x86 which is required to
     exclude the GSI interrupts from the dynamic allocatable range.

     This was detected with the newfangled tablet SoCs which have GPIOs
     and therefor allocate a range of interrupts.  The MSI allocations
     already excluded the GSI range, so we never noticed before.

   - The last missing set_irq_affinity() repair, which was delayed due
     to testing issues

   - A few bug fixes for the armada SoC interrupt controller

   - A memory allocation fix for the TI crossbar interrupt controller

   - A trivial kernel-doc warning fix"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  irqchip: irq-crossbar: Not allocating enough memory
  irqchip: armanda: Sanitize set_irq_affinity()
  genirq: x86: Ensure that dynamic irq allocation does not conflict
  linux/interrupt.h: fix new kernel-doc warnings
  irqchip: armada-370-xp: Fix releasing of MSIs
  irqchip: armada-370-xp: implement the ->check_device() msi_chip operation
  irqchip: armada-370-xp: fix invalid cast of signed value into unsigned variable

136 files changed:
Documentation/devicetree/bindings/arm/arch_timer.txt
Documentation/devicetree/bindings/net/socfpga-dwmac.txt
Documentation/devicetree/bindings/net/stmmac.txt
Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
MAINTAINERS
arch/arc/kernel/entry.S
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/stih415-pinctrl.dtsi
arch/arm/boot/dts/stih416-pinctrl.dtsi
arch/arm/kvm/Kconfig
arch/arm/kvm/mmu.c
arch/hexagon/include/asm/barrier.h [deleted file]
arch/parisc/include/uapi/asm/Kbuild
arch/parisc/include/uapi/asm/resource.h [deleted file]
arch/powerpc/boot/main.c
arch/powerpc/boot/ops.h
arch/powerpc/boot/ps3.c
arch/powerpc/include/asm/opal.h
arch/powerpc/include/uapi/asm/setup.h
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/mm/hash_native_64.c
arch/powerpc/perf/hv-24x7.c
arch/powerpc/perf/hv-gpci.c
arch/powerpc/platforms/powernv/opal-dump.c
arch/powerpc/platforms/powernv/opal-elog.c
arch/powerpc/platforms/powernv/opal-flash.c
arch/powerpc/platforms/powernv/opal-sysparam.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/powernv/smp.c
arch/powerpc/platforms/pseries/hotplug-cpu.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/s390/net/bpf_jit_comp.c
arch/x86/Makefile
arch/x86/kernel/cpu/perf_event_intel_rapl.c
arch/x86/kernel/vsmp_64.c
arch/x86/kvm/vmx.c
drivers/acpi/acpi_processor.c
drivers/acpi/ec.c
drivers/base/dd.c
drivers/base/platform.c
drivers/clocksource/arm_arch_timer.c
drivers/clocksource/zevio-timer.c
drivers/cpufreq/longhaul.c
drivers/cpufreq/powernow-k6.c
drivers/cpufreq/powernow-k7.c
drivers/cpufreq/ppc-corenet-cpufreq.c
drivers/gpu/drm/exynos/exynos_drm_crtc.c
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
drivers/gpu/drm/exynos/exynos_drm_dsi.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h
drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/tegra/dc.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/hwmon/coretemp.c
drivers/infiniband/hw/cxgb4/Kconfig
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/cxgb4/iw_cxgb4.h
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/cxgb4/t4fw_ri_api.h
drivers/md/dm-cache-target.c
drivers/md/dm-thin.c
drivers/md/dm-verity.c
drivers/of/irq.c
drivers/of/platform.c
drivers/of/selftest.c
drivers/of/testcase-data/tests-interrupts.dtsi
drivers/pinctrl/pinctrl-as3722.c
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/pinctrl-tb10x.c
drivers/pinctrl/sh-pfc/pfc-r8a7790.c
drivers/pinctrl/sh-pfc/pfc-r8a7791.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/quirks.c
drivers/s390/cio/chsc.c
fs/aio.c
include/asm-generic/word-at-a-time.h
include/linux/ftrace.h
include/linux/of_irq.h
include/trace/events/module.h
kernel/hrtimer.c
kernel/module.c
kernel/timer.c
kernel/trace/ftrace.c
kernel/trace/trace_events_trigger.c
mm/vmacache.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_priv.h
sound/pci/hda/patch_realtek.c
sound/soc/codecs/alc5623.c
sound/soc/codecs/cs42l52.c
sound/soc/codecs/cs42l73.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/fsl/fsl_spdif.h
sound/soc/intel/sst-dsp-priv.h
sound/soc/intel/sst-haswell-ipc.c
sound/soc/jz4740/Makefile
sound/soc/sh/rcar/src.c
sound/soc/sh/rcar/ssi.c
sound/soc/soc-dapm.c
tools/lib/api/fs/debugfs.c
tools/lib/traceevent/event-parse.c
tools/lib/traceevent/event-parse.h
tools/perf/Makefile.perf
tools/perf/arch/x86/tests/dwarf-unwind.c
tools/perf/arch/x86/tests/regs_load.S
tools/perf/config/Makefile
tools/perf/tests/make
tools/perf/util/machine.c
virt/kvm/arm/vgic.c
virt/kvm/assigned-dev.c
virt/kvm/async_pf.c

index 06fc760..37b2caf 100644 (file)
@@ -19,6 +19,9 @@ to deliver its interrupts via SPIs.
 
 - clock-frequency : The frequency of the main counter, in Hz. Optional.
 
+- always-on : a boolean property. If present, the timer is powered through an
+  always-on power domain, therefore it never loses context.
+
 Example:
 
        timer {
index 636f0ac..2a60cd3 100644 (file)
@@ -23,5 +23,5 @@ gmac0: ethernet@ff700000 {
        interrupt-names = "macirq";
        mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
        clocks = <&emac_0_clk>;
-       clocks-names = "stmmaceth";
+       clock-names = "stmmaceth";
 };
index 80c1fb8..a2acd2b 100644 (file)
@@ -33,7 +33,7 @@ Optional properties:
 - max-frame-size: See ethernet.txt file in the same directory
 - clocks: If present, the first clock should be the GMAC main clock,
   further clocks may be specified in derived bindings.
-- clocks-names: One name for each entry in the clocks property, the
+- clock-names: One name for each entry in the clocks property, the
   first one should be "stmmaceth".
 
 Examples:
index 4bd5be0..26bcb18 100644 (file)
@@ -83,7 +83,7 @@ Example:
                reg             = <0xfe61f080 0x4>;
                reg-names       = "irqmux";
                interrupts      = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
-               interrupts-names = "irqmux";
+               interrupt-names = "irqmux";
                ranges          = <0 0xfe610000 0x5000>;
 
                PIO0: gpio@fe610000 {
@@ -165,7 +165,7 @@ sdhci0:sdhci@fe810000{
        interrupt-parent = <&PIO3>;
        #interrupt-cells = <2>;
        interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */
-       interrupts-names = "card-detect";
+       interrupt-names = "card-detect";
        pinctrl-names = "default";
        pinctrl-0       = <&pinctrl_mmc>;
 };
index 569b26c..60ca079 100644 (file)
@@ -47,7 +47,7 @@ mcasp0: mcasp0@1d00000 {
        reg = <0x100000 0x3000>;
        reg-names "mpu";
        interrupts = <82>, <83>;
-       interrupts-names = "tx", "rx";
+       interrupt-names = "tx", "rx";
        op-mode = <0>;          /* MCASP_IIS_MODE */
        tdm-slots = <2>;
        serial-dir = <
index 74c66de..eff12be 100644 (file)
@@ -13,6 +13,9 @@ Required properties:
     "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP)
 
 - reg - <int> -  I2C slave address
+- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
+  DVDD-supply : power supplies for the device as covered in
+  Documentation/devicetree/bindings/regulator/regulator.txt
 
 
 Optional properties:
@@ -24,9 +27,6 @@ Optional properties:
         3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD
        If this node is not mentioned or if the value is unknown, then
        micbias is set to 2.0V.
-- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply,
-  DVDD-supply : power supplies for the device as covered in
-  Documentation/devicetree/bindings/regulator/regulator.txt
 
 CODEC output pins:
   * HPL
index e67ea24..6bef70b 100644 (file)
@@ -3485,6 +3485,12 @@ S:       Maintained
 F:     drivers/extcon/
 F:     Documentation/extcon/
 
+EXYNOS DP DRIVER
+M:     Jingoo Han <jg1.han@samsung.com>
+L:     dri-devel@lists.freedesktop.org
+S:     Maintained
+F:     drivers/gpu/drm/exynos/exynos_dp*
+
 EXYNOS MIPI DISPLAY DRIVERS
 M:     Inki Dae <inki.dae@samsung.com>
 M:     Donghwa Lee <dh09.lee@samsung.com>
@@ -5108,14 +5114,19 @@ F:      drivers/s390/kvm/
 
 KERNEL VIRTUAL MACHINE (KVM) FOR ARM
 M:     Christoffer Dall <christoffer.dall@linaro.org>
+M:     Marc Zyngier <marc.zyngier@arm.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
 W:     http://systems.cs.columbia.edu/projects/kvm-arm
 S:     Supported
 F:     arch/arm/include/uapi/asm/kvm*
 F:     arch/arm/include/asm/kvm*
 F:     arch/arm/kvm/
+F:     virt/kvm/arm/
+F:     include/kvm/arm_*
 
 KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
+M:     Christoffer Dall <christoffer.dall@linaro.org>
 M:     Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
index 819dd5f..29b82ad 100644 (file)
@@ -614,11 +614,13 @@ resume_user_mode_begin:
 
 resume_kernel_mode:
 
-#ifdef CONFIG_PREEMPT
-
-       ; This is a must for preempt_schedule_irq()
+       ; Disable Interrupts from this point on
+       ; CONFIG_PREEMPT: This is a must for preempt_schedule_irq()
+       ; !CONFIG_PREEMPT: To ensure restore_regs is intr safe
        IRQ_DISABLE     r9
 
+#ifdef CONFIG_PREEMPT
+
        ; Can't preempt if preemption disabled
        GET_CURR_THR_INFO_FROM_SP   r10
        ld  r8, [r10, THREAD_INFO_PREEMPT_COUNT]
index 07f283c..cb6811e 100644 (file)
                              <0x46000000 0x400000>;
                        reg-names = "mpu", "dat";
                        interrupts = <80>, <81>;
-                       interrupts-names = "tx", "rx";
+                       interrupt-names = "tx", "rx";
                        status = "disabled";
                        dmas = <&edma 8>,
                                <&edma 9>;
                              <0x46400000 0x400000>;
                        reg-names = "mpu", "dat";
                        interrupts = <82>, <83>;
-                       interrupts-names = "tx", "rx";
+                       interrupt-names = "tx", "rx";
                        status = "disabled";
                        dmas = <&edma 10>,
                                <&edma 11>;
index 36d523a..d1f8707 100644 (file)
                              <0x46000000 0x400000>;
                        reg-names = "mpu", "dat";
                        interrupts = <80>, <81>;
-                       interrupts-names = "tx", "rx";
+                       interrupt-names = "tx", "rx";
                        status = "disabled";
                        dmas = <&edma 8>,
                               <&edma 9>;
                              <0x46400000 0x400000>;
                        reg-names = "mpu", "dat";
                        interrupts = <82>, <83>;
-                       interrupts-names = "tx", "rx";
+                       interrupt-names = "tx", "rx";
                        status = "disabled";
                        dmas = <&edma 10>,
                               <&edma 11>;
index f09fb10..81df870 100644 (file)
@@ -49,7 +49,7 @@
                        reg             = <0xfe61f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfe610000 0x5000>;
 
                        PIO0: gpio@fe610000 {
                        reg             = <0xfee0f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfee00000 0x8000>;
 
                        PIO5: gpio@fee00000 {
                        reg             = <0xfe82f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfe820000 0x8000>;
 
                        PIO13: gpio@fe820000 {
                        reg             = <0xfd6bf080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfd6b0000 0x3000>;
 
                        PIO100: gpio@fd6b0000 {
                        reg             = <0xfd33f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfd330000 0x5000>;
 
                        PIO103: gpio@fd330000 {
index aeea304..250d5ec 100644 (file)
@@ -53,7 +53,7 @@
                        reg             = <0xfe61f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfe610000 0x6000>;
 
                        PIO0: gpio@fe610000 {
                        reg             = <0xfee0f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfee00000 0x10000>;
 
                        PIO5: gpio@fee00000 {
                        reg             = <0xfe82f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfe820000 0x6000>;
 
                        PIO13: gpio@fe820000 {
                        reg             = <0xfd6bf080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges          = <0 0xfd6b0000 0x3000>;
 
                        PIO100: gpio@fd6b0000 {
                        reg             = <0xfd33f080 0x4>;
                        reg-names       = "irqmux";
                        interrupts      = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupts-names = "irqmux";
+                       interrupt-names = "irqmux";
                        ranges                  = <0 0xfd330000 0x5000>;
 
                        PIO103: gpio@fd330000 {
index 466bd29..4be5bb1 100644 (file)
@@ -23,7 +23,7 @@ config KVM
        select HAVE_KVM_CPU_RELAX_INTERCEPT
        select KVM_MMIO
        select KVM_ARM_HOST
-       depends on ARM_VIRT_EXT && ARM_LPAE
+       depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN
        ---help---
          Support hosting virtualized guest machines. You will also
          need to select one or more of the processor modules below.
index 80bb1e6..16f8049 100644 (file)
@@ -42,6 +42,8 @@ static unsigned long hyp_idmap_start;
 static unsigned long hyp_idmap_end;
 static phys_addr_t hyp_idmap_vector;
 
+#define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t))
+
 #define kvm_pmd_huge(_x)       (pmd_huge(_x) || pmd_trans_huge(_x))
 
 static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
@@ -293,14 +295,14 @@ void free_boot_hyp_pgd(void)
        if (boot_hyp_pgd) {
                unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE);
                unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
-               kfree(boot_hyp_pgd);
+               free_pages((unsigned long)boot_hyp_pgd, pgd_order);
                boot_hyp_pgd = NULL;
        }
 
        if (hyp_pgd)
                unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE);
 
-       kfree(init_bounce_page);
+       free_page((unsigned long)init_bounce_page);
        init_bounce_page = NULL;
 
        mutex_unlock(&kvm_hyp_pgd_mutex);
@@ -330,7 +332,7 @@ void free_hyp_pgds(void)
                for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE)
                        unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE);
 
-               kfree(hyp_pgd);
+               free_pages((unsigned long)hyp_pgd, pgd_order);
                hyp_pgd = NULL;
        }
 
@@ -1024,7 +1026,7 @@ int kvm_mmu_init(void)
                size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start;
                phys_addr_t phys_base;
 
-               init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+               init_bounce_page = (void *)__get_free_page(GFP_KERNEL);
                if (!init_bounce_page) {
                        kvm_err("Couldn't allocate HYP init bounce page\n");
                        err = -ENOMEM;
@@ -1050,8 +1052,9 @@ int kvm_mmu_init(void)
                         (unsigned long)phys_base);
        }
 
-       hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
-       boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL);
+       hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order);
+       boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order);
+
        if (!hyp_pgd || !boot_hyp_pgd) {
                kvm_err("Hyp mode PGD not allocated\n");
                err = -ENOMEM;
diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h
deleted file mode 100644 (file)
index 4e863da..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Memory barrier definitions for the Hexagon architecture
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifndef _ASM_BARRIER_H
-#define _ASM_BARRIER_H
-
-#define rmb()                          barrier()
-#define read_barrier_depends()         barrier()
-#define wmb()                          barrier()
-#define mb()                           barrier()
-#define smp_rmb()                      barrier()
-#define smp_read_barrier_depends()     barrier()
-#define smp_wmb()                      barrier()
-#define smp_mb()                       barrier()
-
-/*  Set a value and use a memory barrier.  Used by the scheduler somewhere.  */
-#define set_mb(var, value) \
-       do { var = value; mb(); } while (0)
-
-#endif /* _ASM_BARRIER_H */
index a580642..348356c 100644 (file)
@@ -1,6 +1,8 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+generic-y += resource.h
+
 header-y += bitsperlong.h
 header-y += byteorder.h
 header-y += errno.h
@@ -13,7 +15,6 @@ header-y += msgbuf.h
 header-y += pdc.h
 header-y += posix_types.h
 header-y += ptrace.h
-header-y += resource.h
 header-y += sembuf.h
 header-y += setup.h
 header-y += shmbuf.h
diff --git a/arch/parisc/include/uapi/asm/resource.h b/arch/parisc/include/uapi/asm/resource.h
deleted file mode 100644 (file)
index 8b06343..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _ASM_PARISC_RESOURCE_H
-#define _ASM_PARISC_RESOURCE_H
-
-#define _STK_LIM_MAX   10 * _STK_LIM
-#include <asm-generic/resource.h>
-
-#endif
index a28f021..d367a0a 100644 (file)
@@ -139,18 +139,18 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen,
  * edit the command line passed to vmlinux (by setting /chosen/bootargs).
  * The buffer is put in it's own section so that tools may locate it easier.
  */
-static char cmdline[COMMAND_LINE_SIZE]
+static char cmdline[BOOT_COMMAND_LINE_SIZE]
        __attribute__((__section__("__builtin_cmdline")));
 
 static void prep_cmdline(void *chosen)
 {
        if (cmdline[0] == '\0')
-               getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
+               getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1);
 
        printf("\n\rLinux/PowerPC load: %s", cmdline);
        /* If possible, edit the command line */
        if (console_ops.edit_cmdline)
-               console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
+               console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE);
        printf("\n\r");
 
        /* Put the command line back into the devtree for the kernel */
@@ -174,7 +174,7 @@ void start(void)
         * built-in command line wasn't set by an external tool */
        if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0'))
                memmove(cmdline, loader_info.cmdline,
-                       min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1));
+                       min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1));
 
        if (console_ops.open && (console_ops.open() < 0))
                exit();
index b3218ce..8aad3c5 100644 (file)
@@ -15,7 +15,7 @@
 #include "types.h"
 #include "string.h"
 
-#define        COMMAND_LINE_SIZE       512
+#define        BOOT_COMMAND_LINE_SIZE  2048
 #define        MAX_PATH_LEN            256
 #define        MAX_PROP_LEN            256 /* What should this be? */
 
index 9954d98..4ec2d86 100644 (file)
@@ -47,13 +47,13 @@ BSS_STACK(4096);
  * The buffer is put in it's own section so that tools may locate it easier.
  */
 
-static char cmdline[COMMAND_LINE_SIZE]
+static char cmdline[BOOT_COMMAND_LINE_SIZE]
        __attribute__((__section__("__builtin_cmdline")));
 
 static void prep_cmdline(void *chosen)
 {
        if (cmdline[0] == '\0')
-               getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
+               getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1);
        else
                setprop_str(chosen, "bootargs", cmdline);
 
index a2efdaa..66ad7a7 100644 (file)
@@ -41,14 +41,14 @@ struct opal_takeover_args {
  * size except the last one in the list to be as well.
  */
 struct opal_sg_entry {
-       void    *data;
-       long    length;
+       __be64 data;
+       __be64 length;
 };
 
-/* sg list */
+/* SG list */
 struct opal_sg_list {
-       unsigned long num_entries;
-       struct opal_sg_list *next;
+       __be64 length;
+       __be64 next;
        struct opal_sg_entry entry[];
 };
 
@@ -858,8 +858,8 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
 int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                      uint32_t addr, __be32 *data, uint32_t sz);
 
-int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id);
-int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
+int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id);
+int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type);
 int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
 int64_t opal_send_ack_elog(uint64_t log_id);
 void opal_resend_pending_logs(void);
@@ -868,23 +868,24 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
 int64_t opal_manage_flash(uint8_t op);
 int64_t opal_update_flash(uint64_t blk_list);
 int64_t opal_dump_init(uint8_t dump_type);
-int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
-int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
+int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size);
+int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type);
 int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
 int64_t opal_dump_ack(uint32_t dump_id);
 int64_t opal_dump_resend_notification(void);
 
-int64_t opal_get_msg(uint64_t buffer, size_t size);
-int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
+int64_t opal_get_msg(uint64_t buffer, uint64_t size);
+int64_t opal_check_completion(uint64_t buffer, uint64_t size, uint64_t token);
 int64_t opal_sync_host_reboot(void);
 int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer,
-               size_t length);
+               uint64_t length);
 int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
-               size_t length);
+               uint64_t length);
 int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
 
 /* Internal functions */
-extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
+extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
+                                  int depth, void *data);
 extern int early_init_dt_scan_recoverable_ranges(unsigned long node,
                                 const char *uname, int depth, void *data);
 
@@ -893,10 +894,6 @@ extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
 
 extern void hvc_opal_init_early(void);
 
-/* Internal functions */
-extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
-                                  int depth, void *data);
-
 extern int opal_notifier_register(struct notifier_block *nb);
 extern int opal_notifier_unregister(struct notifier_block *nb);
 
@@ -906,9 +903,6 @@ extern void opal_notifier_enable(void);
 extern void opal_notifier_disable(void);
 extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val);
 
-extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
-extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
-
 extern int __opal_async_get_token(void);
 extern int opal_async_get_token_interruptible(void);
 extern int __opal_async_release_token(int token);
@@ -916,8 +910,6 @@ extern int opal_async_release_token(int token);
 extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg);
 extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data);
 
-extern void hvc_opal_init_early(void);
-
 struct rtc_time;
 extern int opal_set_rtc_time(struct rtc_time *tm);
 extern void opal_get_rtc_time(struct rtc_time *tm);
@@ -937,6 +929,10 @@ extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
+struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
+                                            unsigned long vmalloc_size);
+void opal_free_sg_list(struct opal_sg_list *sg);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __OPAL_H */
index 552df83..ae3fb68 100644 (file)
@@ -1 +1,6 @@
-#include <asm-generic/setup.h>
+#ifndef _UAPI_ASM_POWERPC_SETUP_H
+#define _UAPI_ASM_POWERPC_SETUP_H
+
+#define COMMAND_LINE_SIZE      2048
+
+#endif /* _UAPI_ASM_POWERPC_SETUP_H */
index 3bd77ed..450850a 100644 (file)
@@ -120,6 +120,7 @@ EXPORT_SYMBOL(giveup_spe);
 EXPORT_SYMBOL(flush_instruction_cache);
 #endif
 EXPORT_SYMBOL(flush_dcache_range);
+EXPORT_SYMBOL(flush_icache_range);
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC32
index 2f3cdb0..658e89d 100644 (file)
@@ -705,7 +705,7 @@ static int __init rtas_flash_init(void)
        if (rtas_token("ibm,update-flash-64-and-reboot") ==
                       RTAS_UNKNOWN_SERVICE) {
                pr_info("rtas_flash: no firmware flash support\n");
-               return 1;
+               return -EINVAL;
        }
 
        rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
index ffbb871..b031f93 100644 (file)
@@ -242,6 +242,12 @@ kvm_novcpu_exit:
  */
        .globl  kvm_start_guest
 kvm_start_guest:
+
+       /* Set runlatch bit the minute you wake up from nap */
+       mfspr   r1, SPRN_CTRLF
+       ori     r1, r1, 1
+       mtspr   SPRN_CTRLT, r1
+
        ld      r2,PACATOC(r13)
 
        li      r0,KVM_HWTHREAD_IN_KVM
@@ -309,6 +315,11 @@ kvm_no_guest:
        li      r0, KVM_HWTHREAD_IN_NAP
        stb     r0, HSTATE_HWTHREAD_STATE(r13)
 kvm_do_nap:
+       /* Clear the runlatch bit before napping */
+       mfspr   r2, SPRN_CTRLF
+       clrrdi  r2, r2, 1
+       mtspr   SPRN_CTRLT, r2
+
        li      r3, LPCR_PECE0
        mfspr   r4, SPRN_LPCR
        rlwimi  r4, r3, 0, LPCR_PECE0 | LPCR_PECE1
@@ -1999,8 +2010,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206)
 
        /*
         * Take a nap until a decrementer or external or doobell interrupt
-        * occurs, with PECE1, PECE0 and PECEDP set in LPCR
+        * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the
+        * runlatch bit before napping.
         */
+       mfspr   r2, SPRN_CTRLF
+       clrrdi  r2, r2, 1
+       mtspr   SPRN_CTRLT, r2
+
        li      r0,1
        stb     r0,HSTATE_HWTHREAD_REQ(r13)
        mfspr   r5,SPRN_LPCR
index 3ea26c2..cf1d325 100644 (file)
@@ -82,17 +82,14 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
                va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
-               /* Add AVAL part */
-               if (psize != apsize) {
-                       /*
-                        * MPSS, 64K base page size and 16MB parge page size
-                        * We don't need all the bits, but rest of the bits
-                        * must be ignored by the processor.
-                        * vpn cover upto 65 bits of va. (0...65) and we need
-                        * 58..64 bits of va.
-                        */
-                       va |= (vpn & 0xfe);
-               }
+               /*
+                * AVAL bits:
+                * We don't need all the bits, but rest of the bits
+                * must be ignored by the processor.
+                * vpn cover upto 65 bits of va. (0...65) and we need
+                * 58..64 bits of va.
+                */
+               va |= (vpn & 0xfe); /* AVAL */
                va |= 1; /* L */
                asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
                             : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
@@ -133,17 +130,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
                va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
-               /* Add AVAL part */
-               if (psize != apsize) {
-                       /*
-                        * MPSS, 64K base page size and 16MB parge page size
-                        * We don't need all the bits, but rest of the bits
-                        * must be ignored by the processor.
-                        * vpn cover upto 65 bits of va. (0...65) and we need
-                        * 58..64 bits of va.
-                        */
-                       va |= (vpn & 0xfe);
-               }
+               /*
+                * AVAL bits:
+                * We don't need all the bits, but rest of the bits
+                * must be ignored by the processor.
+                * vpn cover upto 65 bits of va. (0...65) and we need
+                * 58..64 bits of va.
+                */
+               va |= (vpn & 0xfe);
                va |= 1; /* L */
                asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
                             : : "r"(va) : "memory");
index 297c910..e0766b8 100644 (file)
@@ -155,16 +155,28 @@ static ssize_t read_offset_data(void *dest, size_t dest_len,
        return copy_len;
 }
 
-static unsigned long h_get_24x7_catalog_page(char page[static 4096],
-                                            u32 version, u32 index)
+static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096,
+                                             unsigned long version,
+                                             unsigned long index)
 {
-       WARN_ON(!IS_ALIGNED((unsigned long)page, 4096));
+       pr_devel("h_get_24x7_catalog_page(0x%lx, %lu, %lu)",
+                       phys_4096,
+                       version,
+                       index);
+       WARN_ON(!IS_ALIGNED(phys_4096, 4096));
        return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE,
-                       virt_to_phys(page),
+                       phys_4096,
                        version,
                        index);
 }
 
+static unsigned long h_get_24x7_catalog_page(char page[],
+                                            u64 version, u32 index)
+{
+       return h_get_24x7_catalog_page_(virt_to_phys(page),
+                                       version, index);
+}
+
 static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
                            struct bin_attribute *bin_attr, char *buf,
                            loff_t offset, size_t count)
@@ -173,7 +185,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
        ssize_t ret = 0;
        size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
        loff_t page_offset = 0;
-       uint32_t catalog_version_num = 0;
+       uint64_t catalog_version_num = 0;
        void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
        struct hv_24x7_catalog_page_0 *page_0 = page;
        if (!page)
@@ -185,7 +197,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
                goto e_free;
        }
 
-       catalog_version_num = be32_to_cpu(page_0->version);
+       catalog_version_num = be64_to_cpu(page_0->version);
        catalog_page_len = be32_to_cpu(page_0->length);
        catalog_len = catalog_page_len * 4096;
 
@@ -208,8 +220,9 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
                                page, 4096, page_offset * 4096);
 e_free:
        if (hret)
-               pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n",
-                               catalog_version_num, page_offset, hret);
+               pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:"
+                      " rc=%ld\n",
+                      catalog_version_num, page_offset, hret);
        kfree(page);
 
        pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n",
@@ -243,7 +256,7 @@ e_free:                                                             \
 static DEVICE_ATTR_RO(_name)
 
 PAGE_0_ATTR(catalog_version, "%lld\n",
-               (unsigned long long)be32_to_cpu(page_0->version));
+               (unsigned long long)be64_to_cpu(page_0->version));
 PAGE_0_ATTR(catalog_len, "%lld\n",
                (unsigned long long)be32_to_cpu(page_0->length) * 4096);
 static BIN_ATTR_RO(catalog, 0/* real length varies */);
@@ -485,13 +498,13 @@ static int hv_24x7_init(void)
        struct hv_perf_caps caps;
 
        if (!firmware_has_feature(FW_FEATURE_LPAR)) {
-               pr_info("not a virtualized system, not enabling\n");
+               pr_debug("not a virtualized system, not enabling\n");
                return -ENODEV;
        }
 
        hret = hv_perf_caps_get(&caps);
        if (hret) {
-               pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+               pr_debug("could not obtain capabilities, not enabling, rc=%ld\n",
                                hret);
                return -ENODEV;
        }
index 278ba7b..c9d399a 100644 (file)
@@ -78,7 +78,7 @@ static ssize_t kernel_version_show(struct device *dev,
        return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT);
 }
 
-DEVICE_ATTR_RO(kernel_version);
+static DEVICE_ATTR_RO(kernel_version);
 HV_CAPS_ATTR(version, "0x%x\n");
 HV_CAPS_ATTR(ga, "%d\n");
 HV_CAPS_ATTR(expanded, "%d\n");
@@ -273,13 +273,13 @@ static int hv_gpci_init(void)
        struct hv_perf_caps caps;
 
        if (!firmware_has_feature(FW_FEATURE_LPAR)) {
-               pr_info("not a virtualized system, not enabling\n");
+               pr_debug("not a virtualized system, not enabling\n");
                return -ENODEV;
        }
 
        hret = hv_perf_caps_get(&caps);
        if (hret) {
-               pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n",
+               pr_debug("could not obtain capabilities, not enabling, rc=%ld\n",
                                hret);
                return -ENODEV;
        }
index b9827b0..788a197 100644 (file)
@@ -209,89 +209,20 @@ static struct kobj_type dump_ktype = {
        .default_attrs = dump_default_attrs,
 };
 
-static void free_dump_sg_list(struct opal_sg_list *list)
-{
-       struct opal_sg_list *sg1;
-       while (list) {
-               sg1 = list->next;
-               kfree(list);
-               list = sg1;
-       }
-       list = NULL;
-}
-
-static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
-{
-       struct opal_sg_list *sg1, *list = NULL;
-       void *addr;
-       int64_t size;
-
-       addr = dump->buffer;
-       size = dump->size;
-
-       sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!sg1)
-               goto nomem;
-
-       list = sg1;
-       sg1->num_entries = 0;
-       while (size > 0) {
-               /* Translate virtual address to physical address */
-               sg1->entry[sg1->num_entries].data =
-                       (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
-
-               if (size > PAGE_SIZE)
-                       sg1->entry[sg1->num_entries].length = PAGE_SIZE;
-               else
-                       sg1->entry[sg1->num_entries].length = size;
-
-               sg1->num_entries++;
-               if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
-                       sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
-                       if (!sg1->next)
-                               goto nomem;
-
-                       sg1 = sg1->next;
-                       sg1->num_entries = 0;
-               }
-               addr += PAGE_SIZE;
-               size -= PAGE_SIZE;
-       }
-       return list;
-
-nomem:
-       pr_err("%s : Failed to allocate memory\n", __func__);
-       free_dump_sg_list(list);
-       return NULL;
-}
-
-static void sglist_to_phy_addr(struct opal_sg_list *list)
-{
-       struct opal_sg_list *sg, *next;
-
-       for (sg = list; sg; sg = next) {
-               next = sg->next;
-               /* Don't translate NULL pointer for last entry */
-               if (sg->next)
-                       sg->next = (struct opal_sg_list *)__pa(sg->next);
-               else
-                       sg->next = NULL;
-
-               /* Convert num_entries to length */
-               sg->num_entries =
-                       sg->num_entries * sizeof(struct opal_sg_entry) + 16;
-       }
-}
-
-static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
+static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type)
 {
+       __be32 id, size, type;
        int rc;
-       *type = 0xffffffff;
 
-       rc = opal_dump_info2(id, size, type);
+       type = cpu_to_be32(0xffffffff);
 
+       rc = opal_dump_info2(&id, &size, &type);
        if (rc == OPAL_PARAMETER)
-               rc = opal_dump_info(id, size);
+               rc = opal_dump_info(&id, &size);
+
+       *dump_id = be32_to_cpu(id);
+       *dump_size = be32_to_cpu(size);
+       *dump_type = be32_to_cpu(type);
 
        if (rc)
                pr_warn("%s: Failed to get dump info (%d)\n",
@@ -314,15 +245,12 @@ static int64_t dump_read_data(struct dump_obj *dump)
        }
 
        /* Generate SG list */
-       list = dump_data_to_sglist(dump);
+       list = opal_vmalloc_to_sg_list(dump->buffer, dump->size);
        if (!list) {
                rc = -ENOMEM;
                goto out;
        }
 
-       /* Translate sg list addr to real address */
-       sglist_to_phy_addr(list);
-
        /* First entry address */
        addr = __pa(list);
 
@@ -341,7 +269,7 @@ static int64_t dump_read_data(struct dump_obj *dump)
                        __func__, dump->id);
 
        /* Free SG list */
-       free_dump_sg_list(list);
+       opal_free_sg_list(list);
 
 out:
        return rc;
index ef7bc2a..10268c4 100644 (file)
@@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
 
 static void elog_work_fn(struct work_struct *work)
 {
-       size_t elog_size;
+       __be64 size;
+       __be64 id;
+       __be64 type;
+       uint64_t elog_size;
        uint64_t log_id;
        uint64_t elog_type;
        int rc;
        char name[2+16+1];
 
-       rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
+       rc = opal_get_elog_size(&id, &size, &type);
        if (rc != OPAL_SUCCESS) {
                pr_err("ELOG: Opal log read failed\n");
                return;
        }
 
+       elog_size = be64_to_cpu(size);
+       log_id = be64_to_cpu(id);
+       elog_type = be64_to_cpu(type);
+
        BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE);
 
        if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
index 714ef97..dc487ff 100644 (file)
@@ -79,9 +79,6 @@
 /* XXX: Assume candidate image size is <= 1GB */
 #define MAX_IMAGE_SIZE 0x40000000
 
-/* Flash sg list version */
-#define SG_LIST_VERSION (1UL)
-
 /* Image status */
 enum {
        IMAGE_INVALID,
@@ -131,11 +128,15 @@ static DEFINE_MUTEX(image_data_mutex);
  */
 static inline void opal_flash_validate(void)
 {
-       struct validate_flash_t *args_buf = &validate_flash_data;
+       long ret;
+       void *buf = validate_flash_data.buf;
+       __be32 size, result;
 
-       args_buf->status = opal_validate_flash(__pa(args_buf->buf),
-                                              &(args_buf->buf_size),
-                                              &(args_buf->result));
+       ret = opal_validate_flash(__pa(buf), &size, &result);
+
+       validate_flash_data.status = ret;
+       validate_flash_data.buf_size = be32_to_cpu(size);
+       validate_flash_data.result = be32_to_cpu(result);
 }
 
 /*
@@ -267,94 +268,12 @@ static ssize_t manage_store(struct kobject *kobj,
        return count;
 }
 
-/*
- * Free sg list
- */
-static void free_sg_list(struct opal_sg_list *list)
-{
-       struct opal_sg_list *sg1;
-       while (list) {
-               sg1 = list->next;
-               kfree(list);
-               list = sg1;
-       }
-       list = NULL;
-}
-
-/*
- * Build candidate image scatter gather list
- *
- * list format:
- *   -----------------------------------
- *  |  VER (8) | Entry length in bytes  |
- *   -----------------------------------
- *  |  Pointer to next entry            |
- *   -----------------------------------
- *  |  Address of memory area 1         |
- *   -----------------------------------
- *  |  Length of memory area 1          |
- *   -----------------------------------
- *  |   .........                       |
- *   -----------------------------------
- *  |   .........                       |
- *   -----------------------------------
- *  |  Address of memory area N         |
- *   -----------------------------------
- *  |  Length of memory area N          |
- *   -----------------------------------
- */
-static struct opal_sg_list *image_data_to_sglist(void)
-{
-       struct opal_sg_list *sg1, *list = NULL;
-       void *addr;
-       int size;
-
-       addr = image_data.data;
-       size = image_data.size;
-
-       sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!sg1)
-               return NULL;
-
-       list = sg1;
-       sg1->num_entries = 0;
-       while (size > 0) {
-               /* Translate virtual address to physical address */
-               sg1->entry[sg1->num_entries].data =
-                       (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
-
-               if (size > PAGE_SIZE)
-                       sg1->entry[sg1->num_entries].length = PAGE_SIZE;
-               else
-                       sg1->entry[sg1->num_entries].length = size;
-
-               sg1->num_entries++;
-               if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
-                       sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
-                       if (!sg1->next) {
-                               pr_err("%s : Failed to allocate memory\n",
-                                      __func__);
-                               goto nomem;
-                       }
-
-                       sg1 = sg1->next;
-                       sg1->num_entries = 0;
-               }
-               addr += PAGE_SIZE;
-               size -= PAGE_SIZE;
-       }
-       return list;
-nomem:
-       free_sg_list(list);
-       return NULL;
-}
-
 /*
  * OPAL update flash
  */
 static int opal_flash_update(int op)
 {
-       struct opal_sg_list *sg, *list, *next;
+       struct opal_sg_list *list;
        unsigned long addr;
        int64_t rc = OPAL_PARAMETER;
 
@@ -364,30 +283,13 @@ static int opal_flash_update(int op)
                goto flash;
        }
 
-       list = image_data_to_sglist();
+       list = opal_vmalloc_to_sg_list(image_data.data, image_data.size);
        if (!list)
                goto invalid_img;
 
        /* First entry address */
        addr = __pa(list);
 
-       /* Translate sg list address to absolute */
-       for (sg = list; sg; sg = next) {
-               next = sg->next;
-               /* Don't translate NULL pointer for last entry */
-               if (sg->next)
-                       sg->next = (struct opal_sg_list *)__pa(sg->next);
-               else
-                       sg->next = NULL;
-
-               /*
-                * Convert num_entries to version/length format
-                * to satisfy OPAL.
-                */
-               sg->num_entries = (SG_LIST_VERSION << 56) |
-                       (sg->num_entries * sizeof(struct opal_sg_entry) + 16);
-       }
-
        pr_alert("FLASH: Image is %u bytes\n", image_data.size);
        pr_alert("FLASH: Image update requested\n");
        pr_alert("FLASH: Image will be updated during system reboot\n");
index 6b61472..d202f9b 100644 (file)
@@ -39,10 +39,11 @@ struct param_attr {
        struct kobj_attribute kobj_attr;
 };
 
-static int opal_get_sys_param(u32 param_id, u32 length, void *buffer)
+static ssize_t opal_get_sys_param(u32 param_id, u32 length, void *buffer)
 {
        struct opal_msg msg;
-       int ret, token;
+       ssize_t ret;
+       int token;
 
        token = opal_async_get_token_interruptible();
        if (token < 0) {
@@ -59,7 +60,7 @@ static int opal_get_sys_param(u32 param_id, u32 length, void *buffer)
 
        ret = opal_async_wait_response(token, &msg);
        if (ret) {
-               pr_err("%s: Failed to wait for the async response, %d\n",
+               pr_err("%s: Failed to wait for the async response, %zd\n",
                                __func__, ret);
                goto out_token;
        }
@@ -111,7 +112,7 @@ static ssize_t sys_param_show(struct kobject *kobj,
 {
        struct param_attr *attr = container_of(kobj_attr, struct param_attr,
                        kobj_attr);
-       int ret;
+       ssize_t ret;
 
        mutex_lock(&opal_sysparam_mutex);
        ret = opal_get_sys_param(attr->param_id, attr->param_size,
@@ -121,9 +122,10 @@ static ssize_t sys_param_show(struct kobject *kobj,
 
        memcpy(buf, param_data_buf, attr->param_size);
 
+       ret = attr->param_size;
 out:
        mutex_unlock(&opal_sysparam_mutex);
-       return ret ? ret : attr->param_size;
+       return ret;
 }
 
 static ssize_t sys_param_store(struct kobject *kobj,
@@ -131,14 +133,20 @@ static ssize_t sys_param_store(struct kobject *kobj,
 {
        struct param_attr *attr = container_of(kobj_attr, struct param_attr,
                        kobj_attr);
-       int ret;
+       ssize_t ret;
+
+        /* MAX_PARAM_DATA_LEN is sizeof(param_data_buf) */
+        if (count > MAX_PARAM_DATA_LEN)
+                count = MAX_PARAM_DATA_LEN;
 
        mutex_lock(&opal_sysparam_mutex);
        memcpy(param_data_buf, buf, count);
        ret = opal_set_sys_param(attr->param_id, attr->param_size,
                        param_data_buf);
        mutex_unlock(&opal_sysparam_mutex);
-       return ret ? ret : count;
+       if (!ret)
+               ret = count;
+       return ret;
 }
 
 void __init opal_sys_param_init(void)
@@ -214,13 +222,13 @@ void __init opal_sys_param_init(void)
        }
 
        if (of_property_read_u32_array(sysparam, "param-len", size, count)) {
-               pr_err("SYSPARAM: Missing propery param-len in the DT\n");
+               pr_err("SYSPARAM: Missing property param-len in the DT\n");
                goto out_free_perm;
        }
 
 
        if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) {
-               pr_err("SYSPARAM: Missing propery param-perm in the DT\n");
+               pr_err("SYSPARAM: Missing property param-perm in the DT\n");
                goto out_free_perm;
        }
 
@@ -233,6 +241,12 @@ void __init opal_sys_param_init(void)
 
        /* For each of the parameters, populate the parameter attributes */
        for (i = 0; i < count; i++) {
+               if (size[i] > MAX_PARAM_DATA_LEN) {
+                       pr_warn("SYSPARAM: Not creating parameter %d as size "
+                               "exceeds buffer length\n", i);
+                       continue;
+               }
+
                sysfs_attr_init(&attr[i].kobj_attr.attr);
                attr[i].param_id = id[i];
                attr[i].param_size = size[i];
index 49d2f00..360ad80 100644 (file)
@@ -242,14 +242,14 @@ void opal_notifier_update_evt(uint64_t evt_mask,
 void opal_notifier_enable(void)
 {
        int64_t rc;
-       uint64_t evt = 0;
+       __be64 evt = 0;
 
        atomic_set(&opal_notifier_hold, 0);
 
        /* Process pending events */
        rc = opal_poll_events(&evt);
        if (rc == OPAL_SUCCESS && evt)
-               opal_do_notifier(evt);
+               opal_do_notifier(be64_to_cpu(evt));
 }
 
 void opal_notifier_disable(void)
@@ -529,7 +529,7 @@ static irqreturn_t opal_interrupt(int irq, void *data)
 
        opal_handle_interrupt(virq_to_hw(irq), &events);
 
-       opal_do_notifier(events);
+       opal_do_notifier(be64_to_cpu(events));
 
        return IRQ_HANDLED;
 }
@@ -638,3 +638,66 @@ void opal_shutdown(void)
 
 /* Export this so that test modules can use it */
 EXPORT_SYMBOL_GPL(opal_invalid_call);
+
+/* Convert a region of vmalloc memory to an opal sg list */
+struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
+                                            unsigned long vmalloc_size)
+{
+       struct opal_sg_list *sg, *first = NULL;
+       unsigned long i = 0;
+
+       sg = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!sg)
+               goto nomem;
+
+       first = sg;
+
+       while (vmalloc_size > 0) {
+               uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT;
+               uint64_t length = min(vmalloc_size, PAGE_SIZE);
+
+               sg->entry[i].data = cpu_to_be64(data);
+               sg->entry[i].length = cpu_to_be64(length);
+               i++;
+
+               if (i >= SG_ENTRIES_PER_NODE) {
+                       struct opal_sg_list *next;
+
+                       next = kzalloc(PAGE_SIZE, GFP_KERNEL);
+                       if (!next)
+                               goto nomem;
+
+                       sg->length = cpu_to_be64(
+                                       i * sizeof(struct opal_sg_entry) + 16);
+                       i = 0;
+                       sg->next = cpu_to_be64(__pa(next));
+                       sg = next;
+               }
+
+               vmalloc_addr += length;
+               vmalloc_size -= length;
+       }
+
+       sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16);
+
+       return first;
+
+nomem:
+       pr_err("%s : Failed to allocate memory\n", __func__);
+       opal_free_sg_list(first);
+       return NULL;
+}
+
+void opal_free_sg_list(struct opal_sg_list *sg)
+{
+       while (sg) {
+               uint64_t next = be64_to_cpu(sg->next);
+
+               kfree(sg);
+
+               if (next)
+                       sg = __va(next);
+               else
+                       sg = NULL;
+       }
+}
index 3b2b4fb..98824aa 100644 (file)
@@ -343,7 +343,6 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe)
                                pci_name(dev));
                        continue;
                }
-               pci_dev_get(dev);
                pdn->pcidev = dev;
                pdn->pe_number = pe->pe_number;
                pe->dma_weight += pnv_ioda_dma_weight(dev);
@@ -462,7 +461,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
 
        pe = &phb->ioda.pe_array[pdn->pe_number];
        WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops);
-       set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table);
+       set_iommu_table_base(&pdev->dev, &pe->tce32_table);
 }
 
 static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
index 61cf8fa..8723d32 100644 (file)
@@ -162,18 +162,62 @@ static void pnv_shutdown(void)
 }
 
 #ifdef CONFIG_KEXEC
+static void pnv_kexec_wait_secondaries_down(void)
+{
+       int my_cpu, i, notified = -1;
+
+       my_cpu = get_cpu();
+
+       for_each_online_cpu(i) {
+               uint8_t status;
+               int64_t rc;
+
+               if (i == my_cpu)
+                       continue;
+
+               for (;;) {
+                       rc = opal_query_cpu_status(get_hard_smp_processor_id(i),
+                                                  &status);
+                       if (rc != OPAL_SUCCESS || status != OPAL_THREAD_STARTED)
+                               break;
+                       barrier();
+                       if (i != notified) {
+                               printk(KERN_INFO "kexec: waiting for cpu %d "
+                                      "(physical %d) to enter OPAL\n",
+                                      i, paca[i].hw_cpu_id);
+                               notified = i;
+                       }
+               }
+       }
+}
+
 static void pnv_kexec_cpu_down(int crash_shutdown, int secondary)
 {
        xics_kexec_teardown_cpu(secondary);
 
-       /* Return secondary CPUs to firmware on OPAL v3 */
-       if (firmware_has_feature(FW_FEATURE_OPALv3) && secondary) {
+       /* On OPAL v3, we return all CPUs to firmware */
+
+       if (!firmware_has_feature(FW_FEATURE_OPALv3))
+               return;
+
+       if (secondary) {
+               /* Return secondary CPUs to firmware on OPAL v3 */
                mb();
                get_paca()->kexec_state = KEXEC_STATE_REAL_MODE;
                mb();
 
                /* Return the CPU to OPAL */
                opal_return_cpu();
+       } else if (crash_shutdown) {
+               /*
+                * On crash, we don't wait for secondaries to go
+                * down as they might be unreachable or hung, so
+                * instead we just wait a bit and move on.
+                */
+               mdelay(1);
+       } else {
+               /* Primary waits for the secondaries to have reached OPAL */
+               pnv_kexec_wait_secondaries_down();
        }
 }
 #endif /* CONFIG_KEXEC */
index 908672b..bf5fcd4 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/cputhreads.h>
 #include <asm/xics.h>
 #include <asm/opal.h>
+#include <asm/runlatch.h>
 
 #include "powernv.h"
 
@@ -156,7 +157,9 @@ static void pnv_smp_cpu_kill_self(void)
         */
        mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
        while (!generic_check_cpu_restart(cpu)) {
+               ppc64_runlatch_off();
                power7_nap();
+               ppc64_runlatch_on();
                if (!generic_check_cpu_restart(cpu)) {
                        DBG("CPU%d Unexpected exit while offline !\n", cpu);
                        /* We may be getting an IPI, so we re-enable
index 9b8e050..20d6297 100644 (file)
@@ -88,13 +88,14 @@ void set_default_offline_state(int cpu)
 
 static void rtas_stop_self(void)
 {
-       struct rtas_args args = {
-               .token = cpu_to_be32(rtas_stop_self_token),
+       static struct rtas_args args = {
                .nargs = 0,
                .nret = 1,
                .rets = &args.args[0],
        };
 
+       args.token = cpu_to_be32(rtas_stop_self_token);
+
        local_irq_disable();
 
        BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
index 573b488..7f75c94 100644 (file)
@@ -100,10 +100,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
 
        start_pfn = base >> PAGE_SHIFT;
 
-       if (!pfn_valid(start_pfn)) {
-               memblock_remove(base, memblock_size);
-               return 0;
-       }
+       lock_device_hotplug();
+
+       if (!pfn_valid(start_pfn))
+               goto out;
 
        block_sz = memory_block_size_bytes();
        sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
@@ -114,8 +114,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz
                base += MIN_MEMORY_BLOCK_SIZE;
        }
 
+out:
        /* Update memory regions for memory remove */
        memblock_remove(base, memblock_size);
+       unlock_device_hotplug();
        return 0;
 }
 
index 64603a1..4914fd3 100644 (file)
@@ -1058,7 +1058,7 @@ static int __init apm821xx_pciex_core_init(struct device_node *np)
        return 1;
 }
 
-static int apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
+static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
 {
        u32 val;
 
index 9c36dc3..452d3eb 100644 (file)
@@ -276,7 +276,6 @@ static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter)
        case BPF_S_LD_W_IND:
        case BPF_S_LD_H_IND:
        case BPF_S_LD_B_IND:
-       case BPF_S_LDX_B_MSH:
        case BPF_S_LD_IMM:
        case BPF_S_LD_MEM:
        case BPF_S_MISC_TXA:
index d1b7c37..ce6ad7e 100644 (file)
@@ -83,7 +83,9 @@ else
         KBUILD_CFLAGS += -m64
 
         # Don't autogenerate traditional x87, MMX or SSE instructions
-        KBUILD_CFLAGS += -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387
+        KBUILD_CFLAGS += -mno-mmx -mno-sse
+        KBUILD_CFLAGS += $(call cc-option,-mno-80387)
+        KBUILD_CFLAGS += $(call cc-option,-mno-fp-ret-in-387)
 
        # Use -mpreferred-stack-boundary=3 if supported.
        KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
index 7c87424..619f769 100644 (file)
@@ -543,7 +543,8 @@ static int rapl_cpu_prepare(int cpu)
        if (phys_id < 0)
                return -1;
 
-       if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+       /* protect rdmsrl() to handle virtualization */
+       if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
                return -1;
 
        pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
index f6584a9..5edc34b 100644 (file)
@@ -26,6 +26,9 @@
 
 #define TOPOLOGY_REGISTER_OFFSET 0x10
 
+/* Flag below is initialized once during vSMP PCI initialization. */
+static int irq_routing_comply = 1;
+
 #if defined CONFIG_PCI && defined CONFIG_PARAVIRT
 /*
  * Interrupt control on vSMPowered systems:
@@ -101,6 +104,10 @@ static void __init set_vsmp_pv_ops(void)
 #ifdef CONFIG_SMP
        if (cap & ctl & BIT(8)) {
                ctl &= ~BIT(8);
+
+               /* Interrupt routing set to ignore */
+               irq_routing_comply = 0;
+
 #ifdef CONFIG_PROC_FS
                /* Don't let users change irq affinity via procfs */
                no_irq_affinity = 1;
@@ -218,7 +225,9 @@ static void vsmp_apic_post_init(void)
 {
        /* need to update phys_pkg_id */
        apic->phys_pkg_id = apicid_phys_pkg_id;
-       apic->vector_allocation_domain = fill_vector_allocation_domain;
+
+       if (!irq_routing_comply)
+               apic->vector_allocation_domain = fill_vector_allocation_domain;
 }
 
 void __init vsmp_init(void)
index 1f68c58..33e8c02 100644 (file)
@@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
                                [number##_HIGH] = VMCS12_OFFSET(name)+4
 
 
-static const unsigned long shadow_read_only_fields[] = {
+static unsigned long shadow_read_only_fields[] = {
        /*
         * We do NOT shadow fields that are modified when L0
         * traps and emulates any vmx instruction (e.g. VMPTRLD,
@@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = {
        GUEST_LINEAR_ADDRESS,
        GUEST_PHYSICAL_ADDRESS
 };
-static const int max_shadow_read_only_fields =
+static int max_shadow_read_only_fields =
        ARRAY_SIZE(shadow_read_only_fields);
 
-static const unsigned long shadow_read_write_fields[] = {
+static unsigned long shadow_read_write_fields[] = {
        GUEST_RIP,
        GUEST_RSP,
        GUEST_CR0,
@@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = {
        HOST_FS_SELECTOR,
        HOST_GS_SELECTOR
 };
-static const int max_shadow_read_write_fields =
+static int max_shadow_read_write_fields =
        ARRAY_SIZE(shadow_read_write_fields);
 
 static const unsigned short vmcs_field_to_offset_table[] = {
@@ -3009,6 +3009,41 @@ static void free_kvm_area(void)
        }
 }
 
+static void init_vmcs_shadow_fields(void)
+{
+       int i, j;
+
+       /* No checks for read only fields yet */
+
+       for (i = j = 0; i < max_shadow_read_write_fields; i++) {
+               switch (shadow_read_write_fields[i]) {
+               case GUEST_BNDCFGS:
+                       if (!vmx_mpx_supported())
+                               continue;
+                       break;
+               default:
+                       break;
+               }
+
+               if (j < i)
+                       shadow_read_write_fields[j] =
+                               shadow_read_write_fields[i];
+               j++;
+       }
+       max_shadow_read_write_fields = j;
+
+       /* shadowed fields guest access without vmexit */
+       for (i = 0; i < max_shadow_read_write_fields; i++) {
+               clear_bit(shadow_read_write_fields[i],
+                         vmx_vmwrite_bitmap);
+               clear_bit(shadow_read_write_fields[i],
+                         vmx_vmread_bitmap);
+       }
+       for (i = 0; i < max_shadow_read_only_fields; i++)
+               clear_bit(shadow_read_only_fields[i],
+                         vmx_vmread_bitmap);
+}
+
 static __init int alloc_kvm_area(void)
 {
        int cpu;
@@ -3039,6 +3074,8 @@ static __init int hardware_setup(void)
                enable_vpid = 0;
        if (!cpu_has_vmx_shadow_vmcs())
                enable_shadow_vmcs = 0;
+       if (enable_shadow_vmcs)
+               init_vmcs_shadow_fields();
 
        if (!cpu_has_vmx_ept() ||
            !cpu_has_vmx_ept_4levels()) {
@@ -8803,14 +8840,6 @@ static int __init vmx_init(void)
 
        memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
        memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
-       /* shadowed read/write fields */
-       for (i = 0; i < max_shadow_read_write_fields; i++) {
-               clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap);
-               clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap);
-       }
-       /* shadowed read only fields */
-       for (i = 0; i < max_shadow_read_only_fields; i++)
-               clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap);
 
        /*
         * Allow direct access to the PC debug port (it is often used for I/O
index c29c2c3..b06f5f5 100644 (file)
@@ -170,6 +170,9 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr)
        acpi_status status;
        int ret;
 
+       if (pr->apic_id == -1)
+               return -ENODEV;
+
        status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
        if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
                return -ENODEV;
@@ -260,10 +263,8 @@ static int acpi_processor_get_info(struct acpi_device *device)
        }
 
        apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id);
-       if (apic_id < 0) {
+       if (apic_id < 0)
                acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n");
-               return -ENODEV;
-       }
        pr->apic_id = apic_id;
 
        cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
index d7d32c2..ad11ba4 100644 (file)
@@ -206,13 +206,13 @@ unlock:
        spin_unlock_irqrestore(&ec->lock, flags);
 }
 
-static int acpi_ec_sync_query(struct acpi_ec *ec);
+static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
 
 static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 {
        if (state & ACPI_EC_FLAG_SCI) {
                if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-                       return acpi_ec_sync_query(ec);
+                       return acpi_ec_sync_query(ec, NULL);
        }
        return 0;
 }
@@ -443,10 +443,8 @@ acpi_handle ec_get_handle(void)
 
 EXPORT_SYMBOL(ec_get_handle);
 
-static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data);
-
 /*
- * Clears stale _Q events that might have accumulated in the EC.
+ * Process _Q events that might have accumulated in the EC.
  * Run with locked ec mutex.
  */
 static void acpi_ec_clear(struct acpi_ec *ec)
@@ -455,7 +453,7 @@ static void acpi_ec_clear(struct acpi_ec *ec)
        u8 value = 0;
 
        for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
-               status = acpi_ec_query_unlocked(ec, &value);
+               status = acpi_ec_sync_query(ec, &value);
                if (status || !value)
                        break;
        }
@@ -582,13 +580,18 @@ static void acpi_ec_run(void *cxt)
        kfree(handler);
 }
 
-static int acpi_ec_sync_query(struct acpi_ec *ec)
+static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data)
 {
        u8 value = 0;
        int status;
        struct acpi_ec_query_handler *handler, *copy;
-       if ((status = acpi_ec_query_unlocked(ec, &value)))
+
+       status = acpi_ec_query_unlocked(ec, &value);
+       if (data)
+               *data = value;
+       if (status)
                return status;
+
        list_for_each_entry(handler, &ec->list, node) {
                if (value == handler->query_bit) {
                        /* have custom handler for this bit */
@@ -612,7 +615,7 @@ static void acpi_ec_gpe_query(void *ec_cxt)
        if (!ec)
                return;
        mutex_lock(&ec->mutex);
-       acpi_ec_sync_query(ec);
+       acpi_ec_sync_query(ec, NULL);
        mutex_unlock(&ec->mutex);
 }
 
index 8986b9f..62ec61e 100644 (file)
@@ -52,6 +52,7 @@ static DEFINE_MUTEX(deferred_probe_mutex);
 static LIST_HEAD(deferred_probe_pending_list);
 static LIST_HEAD(deferred_probe_active_list);
 static struct workqueue_struct *deferred_wq;
+static atomic_t deferred_trigger_count = ATOMIC_INIT(0);
 
 /**
  * deferred_probe_work_func() - Retry probing devices in the active list.
@@ -135,6 +136,17 @@ static bool driver_deferred_probe_enable = false;
  * This functions moves all devices from the pending list to the active
  * list and schedules the deferred probe workqueue to process them.  It
  * should be called anytime a driver is successfully bound to a device.
+ *
+ * Note, there is a race condition in multi-threaded probe. In the case where
+ * more than one device is probing at the same time, it is possible for one
+ * probe to complete successfully while another is about to defer. If the second
+ * depends on the first, then it will get put on the pending list after the
+ * trigger event has already occured and will be stuck there.
+ *
+ * The atomic 'deferred_trigger_count' is used to determine if a successful
+ * trigger has occurred in the midst of probing a driver. If the trigger count
+ * changes in the midst of a probe, then deferred processing should be triggered
+ * again.
  */
 static void driver_deferred_probe_trigger(void)
 {
@@ -147,6 +159,7 @@ static void driver_deferred_probe_trigger(void)
         * into the active list so they can be retried by the workqueue
         */
        mutex_lock(&deferred_probe_mutex);
+       atomic_inc(&deferred_trigger_count);
        list_splice_tail_init(&deferred_probe_pending_list,
                              &deferred_probe_active_list);
        mutex_unlock(&deferred_probe_mutex);
@@ -265,6 +278,7 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
 static int really_probe(struct device *dev, struct device_driver *drv)
 {
        int ret = 0;
+       int local_trigger_count = atomic_read(&deferred_trigger_count);
 
        atomic_inc(&probe_count);
        pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
@@ -310,6 +324,9 @@ probe_failed:
                /* Driver requested deferred probing */
                dev_info(dev, "Driver %s requests probe deferral\n", drv->name);
                driver_deferred_probe_add(dev);
+               /* Did a trigger occur while probing? Need to re-trigger if yes */
+               if (local_trigger_count != atomic_read(&deferred_trigger_count))
+                       driver_deferred_probe_trigger();
        } else if (ret != -ENODEV && ret != -ENXIO) {
                /* driver matched but the probe failed */
                printk(KERN_WARNING
index e714709..5b47210 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/string.h>
 #include <linux/platform_device.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
@@ -87,7 +88,11 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
                return -ENXIO;
        return dev->archdata.irqs[num];
 #else
-       struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
+       struct resource *r;
+       if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
+               return of_irq_get(dev->dev.of_node, num);
+
+       r = platform_get_resource(dev, IORESOURCE_IRQ, num);
 
        return r ? r->start : -ENXIO;
 #endif
index 57e823c..5163ec1 100644 (file)
@@ -66,6 +66,7 @@ static int arch_timer_ppi[MAX_TIMER_PPI];
 static struct clock_event_device __percpu *arch_timer_evt;
 
 static bool arch_timer_use_virtual = true;
+static bool arch_timer_c3stop;
 static bool arch_timer_mem_use_virtual;
 
 /*
@@ -263,7 +264,8 @@ static void __arch_timer_setup(unsigned type,
        clk->features = CLOCK_EVT_FEAT_ONESHOT;
 
        if (type == ARCH_CP15_TIMER) {
-               clk->features |= CLOCK_EVT_FEAT_C3STOP;
+               if (arch_timer_c3stop)
+                       clk->features |= CLOCK_EVT_FEAT_C3STOP;
                clk->name = "arch_sys_timer";
                clk->rating = 450;
                clk->cpumask = cpumask_of(smp_processor_id());
@@ -665,6 +667,8 @@ static void __init arch_timer_init(struct device_node *np)
                }
        }
 
+       arch_timer_c3stop = !of_property_read_bool(np, "always-on");
+
        arch_timer_register();
        arch_timer_common_init();
 }
index ca81809..7ce4421 100644 (file)
@@ -212,4 +212,9 @@ error_free:
        return ret;
 }
 
-CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_add);
+static void __init zevio_timer_init(struct device_node *node)
+{
+       BUG_ON(zevio_timer_add(node));
+}
+
+CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init);
index d00e5d1..5c4369b 100644 (file)
@@ -242,7 +242,7 @@ static void do_powersaver(int cx_address, unsigned int mults_index,
  * Sets a new clock ratio.
  */
 
-static void longhaul_setstate(struct cpufreq_policy *policy,
+static int longhaul_setstate(struct cpufreq_policy *policy,
                unsigned int table_index)
 {
        unsigned int mults_index;
@@ -258,10 +258,12 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
        /* Safety precautions */
        mult = mults[mults_index & 0x1f];
        if (mult == -1)
-               return;
+               return -EINVAL;
+
        speed = calc_speed(mult);
        if ((speed > highest_speed) || (speed < lowest_speed))
-               return;
+               return -EINVAL;
+
        /* Voltage transition before frequency transition? */
        if (can_scale_voltage && longhaul_index < table_index)
                dir = 1;
@@ -269,8 +271,6 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
        freqs.old = calc_speed(longhaul_get_cpu_mult());
        freqs.new = speed;
 
-       cpufreq_freq_transition_begin(policy, &freqs);
-
        pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
                        fsb, mult/10, mult%10, print_speed(speed/1000));
 retry_loop:
@@ -385,12 +385,14 @@ retry_loop:
                        goto retry_loop;
                }
        }
-       /* Report true CPU frequency */
-       cpufreq_freq_transition_end(policy, &freqs, 0);
 
-       if (!bm_timeout)
+       if (!bm_timeout) {
                printk(KERN_INFO PFX "Warning: Timeout while waiting for "
                                "idle PCI bus.\n");
+               return -EBUSY;
+       }
+
+       return 0;
 }
 
 /*
@@ -631,9 +633,10 @@ static int longhaul_target(struct cpufreq_policy *policy,
        unsigned int i;
        unsigned int dir = 0;
        u8 vid, current_vid;
+       int retval = 0;
 
        if (!can_scale_voltage)
-               longhaul_setstate(policy, table_index);
+               retval = longhaul_setstate(policy, table_index);
        else {
                /* On test system voltage transitions exceeding single
                 * step up or down were turning motherboard off. Both
@@ -648,7 +651,7 @@ static int longhaul_target(struct cpufreq_policy *policy,
                while (i != table_index) {
                        vid = (longhaul_table[i].driver_data >> 8) & 0x1f;
                        if (vid != current_vid) {
-                               longhaul_setstate(policy, i);
+                               retval = longhaul_setstate(policy, i);
                                current_vid = vid;
                                msleep(200);
                        }
@@ -657,10 +660,11 @@ static int longhaul_target(struct cpufreq_policy *policy,
                        else
                                i--;
                }
-               longhaul_setstate(policy, table_index);
+               retval = longhaul_setstate(policy, table_index);
        }
+
        longhaul_index = table_index;
-       return 0;
+       return retval;
 }
 
 
@@ -968,7 +972,15 @@ static void __exit longhaul_exit(void)
 
        for (i = 0; i < numscales; i++) {
                if (mults[i] == maxmult) {
+                       struct cpufreq_freqs freqs;
+
+                       freqs.old = policy->cur;
+                       freqs.new = longhaul_table[i].frequency;
+                       freqs.flags = 0;
+
+                       cpufreq_freq_transition_begin(policy, &freqs);
                        longhaul_setstate(policy, i);
+                       cpufreq_freq_transition_end(policy, &freqs, 0);
                        break;
                }
        }
index 49f120e..78904e6 100644 (file)
@@ -138,22 +138,14 @@ static void powernow_k6_set_cpu_multiplier(unsigned int best_i)
 static int powernow_k6_target(struct cpufreq_policy *policy,
                unsigned int best_i)
 {
-       struct cpufreq_freqs freqs;
 
        if (clock_ratio[best_i].driver_data > max_multiplier) {
                printk(KERN_ERR PFX "invalid target frequency\n");
                return -EINVAL;
        }
 
-       freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
-       freqs.new = busfreq * clock_ratio[best_i].driver_data;
-
-       cpufreq_freq_transition_begin(policy, &freqs);
-
        powernow_k6_set_cpu_multiplier(best_i);
 
-       cpufreq_freq_transition_end(policy, &freqs, 0);
-
        return 0;
 }
 
@@ -227,9 +219,20 @@ have_busfreq:
 static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
 {
        unsigned int i;
-       for (i = 0; i < 8; i++) {
-               if (i == max_multiplier)
+
+       for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+               if (clock_ratio[i].driver_data == max_multiplier) {
+                       struct cpufreq_freqs freqs;
+
+                       freqs.old = policy->cur;
+                       freqs.new = clock_ratio[i].frequency;
+                       freqs.flags = 0;
+
+                       cpufreq_freq_transition_begin(policy, &freqs);
                        powernow_k6_target(policy, i);
+                       cpufreq_freq_transition_end(policy, &freqs, 0);
+                       break;
+               }
        }
        return 0;
 }
index f911645..e61e224 100644 (file)
@@ -269,8 +269,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
 
        freqs.new = powernow_table[index].frequency;
 
-       cpufreq_freq_transition_begin(policy, &freqs);
-
        /* Now do the magic poking into the MSRs.  */
 
        if (have_a0 == 1)       /* A0 errata 5 */
@@ -290,8 +288,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
        if (have_a0 == 1)
                local_irq_enable();
 
-       cpufreq_freq_transition_end(policy, &freqs, 0);
-
        return 0;
 }
 
index a1ca3dd..0af618a 100644 (file)
@@ -138,6 +138,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
        struct cpufreq_frequency_table *table;
        struct cpu_data *data;
        unsigned int cpu = policy->cpu;
+       u64 transition_latency_hz;
 
        np = of_get_cpu_node(cpu, NULL);
        if (!np)
@@ -205,8 +206,10 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
        for_each_cpu(i, per_cpu(cpu_mask, cpu))
                per_cpu(cpu_data, i) = data;
 
+       transition_latency_hz = 12ULL * NSEC_PER_SEC;
        policy->cpuinfo.transition_latency =
-                               (12ULL * NSEC_PER_SEC) / fsl_get_sys_freq();
+               do_div(transition_latency_hz, fsl_get_sys_freq());
+
        of_node_put(np);
 
        return 0;
index e930d4f..1ef5ab9 100644 (file)
@@ -145,6 +145,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
 
        plane->crtc = crtc;
        plane->fb = crtc->primary->fb;
+       drm_framebuffer_reference(plane->fb);
 
        return 0;
 }
index c786cd4..2a3ad24 100644 (file)
@@ -263,7 +263,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
        buffer->sgt = sgt;
        exynos_gem_obj->base.import_attach = attach;
 
-       DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", buffer->dma_addr,
+       DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", &buffer->dma_addr,
                                                                buffer->size);
 
        return &exynos_gem_obj->base;
index eb73e3b..4ac4381 100644 (file)
@@ -1426,9 +1426,9 @@ static int exynos_dsi_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        dsi->reg_base = devm_ioremap_resource(&pdev->dev, res);
-       if (!dsi->reg_base) {
+       if (IS_ERR(dsi->reg_base)) {
                dev_err(&pdev->dev, "failed to remap io region\n");
-               return -EADDRNOTAVAIL;
+               return PTR_ERR(dsi->reg_base);
        }
 
        dsi->phy = devm_phy_get(&pdev->dev, "dsim");
index 7afead9..852f2da 100644 (file)
@@ -220,7 +220,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
 
        win_data->enabled = true;
 
-       DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr);
+       DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr);
 
        if (ctx->vblank_on)
                schedule_work(&ctx->work);
index ab5e93c..62a5c36 100644 (file)
@@ -50,7 +50,7 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full)
 
        /* Full ppgtt disabled by default for now due to issues. */
        if (full)
-               return false; /* HAS_PPGTT(dev) */
+               return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2);
        else
                return HAS_ALIASING_PPGTT(dev);
 }
index 7753249..f98ba4e 100644 (file)
@@ -1362,10 +1362,20 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev,
        spin_lock(&dev_priv->irq_lock);
        for (i = 1; i < HPD_NUM_PINS; i++) {
 
-               WARN_ONCE(hpd[i] & hotplug_trigger &&
-                         dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED,
-                         "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n",
-                         hotplug_trigger, i, hpd[i]);
+               if (hpd[i] & hotplug_trigger &&
+                   dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) {
+                       /*
+                        * On GMCH platforms the interrupt mask bits only
+                        * prevent irq generation, not the setting of the
+                        * hotplug bits itself. So only WARN about unexpected
+                        * interrupts on saner platforms.
+                        */
+                       WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev),
+                                 "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n",
+                                 hotplug_trigger, i, hpd[i]);
+
+                       continue;
+               }
 
                if (!(hpd[i] & hotplug_trigger) ||
                    dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED)
index 9f5b18d..c77af69 100644 (file)
@@ -827,6 +827,7 @@ enum punit_power_well {
 # define MI_FLUSH_ENABLE                               (1 << 12)
 # define ASYNC_FLIP_PERF_DISABLE                       (1 << 14)
 # define MODE_IDLE                                     (1 << 9)
+# define STOP_RING                                     (1 << 8)
 
 #define GEN6_GT_MODE   0x20d0
 #define GEN7_GT_MODE   0x7008
index dae976f..69bcc42 100644 (file)
@@ -9654,11 +9654,22 @@ intel_pipe_config_compare(struct drm_device *dev,
        PIPE_CONF_CHECK_I(pipe_src_w);
        PIPE_CONF_CHECK_I(pipe_src_h);
 
-       PIPE_CONF_CHECK_I(gmch_pfit.control);
-       /* pfit ratios are autocomputed by the hw on gen4+ */
-       if (INTEL_INFO(dev)->gen < 4)
-               PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
-       PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+       /*
+        * FIXME: BIOS likes to set up a cloned config with lvds+external
+        * screen. Since we don't yet re-compute the pipe config when moving
+        * just the lvds port away to another pipe the sw tracking won't match.
+        *
+        * Proper atomic modesets with recomputed global state will fix this.
+        * Until then just don't check gmch state for inherited modes.
+        */
+       if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) {
+               PIPE_CONF_CHECK_I(gmch_pfit.control);
+               /* pfit ratios are autocomputed by the hw on gen4+ */
+               if (INTEL_INFO(dev)->gen < 4)
+                       PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios);
+               PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits);
+       }
+
        PIPE_CONF_CHECK_I(pch_pfit.enabled);
        if (current_config->pch_pfit.enabled) {
                PIPE_CONF_CHECK_I(pch_pfit.pos);
@@ -11616,6 +11627,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                            base.head) {
                memset(&crtc->config, 0, sizeof(crtc->config));
 
+               crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE;
+
                crtc->active = dev_priv->display.get_pipe_config(crtc,
                                                                 &crtc->config);
 
index d2a5588..dfa8528 100644 (file)
@@ -3619,7 +3619,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 {
        struct drm_connector *connector = &intel_connector->base;
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct intel_encoder *intel_encoder = &intel_dig_port->base;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_display_mode *fixed_mode = NULL;
        bool has_dpcd;
@@ -3629,6 +3630,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        if (!is_edp(intel_dp))
                return true;
 
+       /* The VDD bit needs a power domain reference, so if the bit is already
+        * enabled when we boot, grab this reference. */
+       if (edp_have_panel_vdd(intel_dp)) {
+               enum intel_display_power_domain power_domain;
+               power_domain = intel_display_port_power_domain(intel_encoder);
+               intel_display_power_get(dev_priv, power_domain);
+       }
+
        /* Cache DPCD and EDID for edp. */
        intel_edp_panel_vdd_on(intel_dp);
        has_dpcd = intel_dp_get_dpcd(intel_dp);
index 0542de9..328b1a7 100644 (file)
@@ -236,7 +236,8 @@ struct intel_crtc_config {
         * tracked with quirk flags so that fastboot and state checker can act
         * accordingly.
         */
-#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */
+#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS      (1<<0) /* unreliable sync mode.flags */
+#define PIPE_CONFIG_QUIRK_INHERITED_MODE       (1<<1) /* mode inherited from firmware */
        unsigned long quirks;
 
        /* User requested mode, only valid as a starting point to
index b4d44e6..fce4a0d 100644 (file)
@@ -132,6 +132,16 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
        mutex_lock(&dev->struct_mutex);
 
+       if (intel_fb &&
+           (sizes->fb_width > intel_fb->base.width ||
+            sizes->fb_height > intel_fb->base.height)) {
+               DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d),"
+                             " releasing it\n",
+                             intel_fb->base.width, intel_fb->base.height,
+                             sizes->fb_width, sizes->fb_height);
+               drm_framebuffer_unreference(&intel_fb->base);
+               intel_fb = ifbdev->fb = NULL;
+       }
        if (!intel_fb || WARN_ON(!intel_fb->obj)) {
                DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n");
                ret = intelfb_alloc(helper, sizes);
index b0413e1..157267a 100644 (file)
@@ -821,11 +821,11 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
        }
 }
 
-static int hdmi_portclock_limit(struct intel_hdmi *hdmi)
+static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
 {
        struct drm_device *dev = intel_hdmi_to_dev(hdmi);
 
-       if (!hdmi->has_hdmi_sink || IS_G4X(dev))
+       if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
                return 165000;
        else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
                return 300000;
@@ -837,7 +837,8 @@ static enum drm_mode_status
 intel_hdmi_mode_valid(struct drm_connector *connector,
                      struct drm_display_mode *mode)
 {
-       if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector)))
+       if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector),
+                                              true))
                return MODE_CLOCK_HIGH;
        if (mode->clock < 20000)
                return MODE_CLOCK_LOW;
@@ -879,7 +880,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
        struct drm_device *dev = encoder->base.dev;
        struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
        int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2;
-       int portclock_limit = hdmi_portclock_limit(intel_hdmi);
+       int portclock_limit = hdmi_portclock_limit(intel_hdmi, false);
        int desired_bpp;
 
        if (intel_hdmi->color_range_auto) {
index 6bc68bd..79fb4cc 100644 (file)
@@ -437,32 +437,41 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring)
        I915_WRITE(HWS_PGA, addr);
 }
 
-static int init_ring_common(struct intel_ring_buffer *ring)
+static bool stop_ring(struct intel_ring_buffer *ring)
 {
-       struct drm_device *dev = ring->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj = ring->obj;
-       int ret = 0;
-       u32 head;
+       struct drm_i915_private *dev_priv = to_i915(ring->dev);
 
-       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+       if (!IS_GEN2(ring->dev)) {
+               I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING));
+               if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) {
+                       DRM_ERROR("%s :timed out trying to stop ring\n", ring->name);
+                       return false;
+               }
+       }
 
-       /* Stop the ring if it's running. */
        I915_WRITE_CTL(ring, 0);
        I915_WRITE_HEAD(ring, 0);
        ring->write_tail(ring, 0);
-       if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000))
-               DRM_ERROR("%s :timed out trying to stop ring\n", ring->name);
 
-       if (I915_NEED_GFX_HWS(dev))
-               intel_ring_setup_status_page(ring);
-       else
-               ring_setup_phys_status_page(ring);
+       if (!IS_GEN2(ring->dev)) {
+               (void)I915_READ_CTL(ring);
+               I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING));
+       }
 
-       head = I915_READ_HEAD(ring) & HEAD_ADDR;
+       return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0;
+}
 
-       /* G45 ring initialization fails to reset head to zero */
-       if (head != 0) {
+static int init_ring_common(struct intel_ring_buffer *ring)
+{
+       struct drm_device *dev = ring->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_gem_object *obj = ring->obj;
+       int ret = 0;
+
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
+
+       if (!stop_ring(ring)) {
+               /* G45 ring initialization often fails to reset head to zero */
                DRM_DEBUG_KMS("%s head not reset to zero "
                              "ctl %08x head %08x tail %08x start %08x\n",
                              ring->name,
@@ -471,9 +480,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
                              I915_READ_TAIL(ring),
                              I915_READ_START(ring));
 
-               I915_WRITE_HEAD(ring, 0);
-
-               if (I915_READ_HEAD(ring) & HEAD_ADDR) {
+               if (!stop_ring(ring)) {
                        DRM_ERROR("failed to set %s head to zero "
                                  "ctl %08x head %08x tail %08x start %08x\n",
                                  ring->name,
@@ -481,9 +488,16 @@ static int init_ring_common(struct intel_ring_buffer *ring)
                                  I915_READ_HEAD(ring),
                                  I915_READ_TAIL(ring),
                                  I915_READ_START(ring));
+                       ret = -EIO;
+                       goto out;
                }
        }
 
+       if (I915_NEED_GFX_HWS(dev))
+               intel_ring_setup_status_page(ring);
+       else
+               ring_setup_phys_status_page(ring);
+
        /* Initialize the ring. This must happen _after_ we've cleared the ring
         * registers with the above sequence (the readback of the HEAD registers
         * also enforces ordering), otherwise the hw might lose the new ring
index 270a6a9..2b91c4b 100644 (file)
@@ -34,6 +34,7 @@ struct  intel_hw_status_page {
 #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
 
 #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base))
+#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val)
 
 enum intel_ring_hangcheck_action {
        HANGCHECK_IDLE = 0,
index 3e6c0f3..ef9957d 100644 (file)
@@ -510,9 +510,8 @@ static void update_cursor(struct drm_crtc *crtc)
                                        MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN);
                } else {
                        /* disable cursor: */
-                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), 0);
-                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
-                                       MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB));
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma),
+                                       mdp4_kms->blank_cursor_iova);
                }
 
                /* and drop the iova ref + obj rev when done scanning out: */
@@ -574,11 +573,9 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
 
        if (old_bo) {
                /* drop our previous reference: */
-               msm_gem_put_iova(old_bo, mdp4_kms->id);
-               drm_gem_object_unreference_unlocked(old_bo);
+               drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, old_bo);
        }
 
-       crtc_flush(crtc);
        request_pending(crtc, PENDING_CURSOR);
 
        return 0;
index c740ccd..8edd531 100644 (file)
@@ -70,12 +70,12 @@ irqreturn_t mdp4_irq(struct msm_kms *kms)
 
        VERB("status=%08x", status);
 
+       mdp_dispatch_irqs(mdp_kms, status);
+
        for (id = 0; id < priv->num_crtcs; id++)
                if (status & mdp4_crtc_vblank(priv->crtcs[id]))
                        drm_handle_vblank(dev, id);
 
-       mdp_dispatch_irqs(mdp_kms, status);
-
        return IRQ_HANDLED;
 }
 
index 272e707..0bb4faa 100644 (file)
@@ -144,6 +144,10 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
 static void mdp4_destroy(struct msm_kms *kms)
 {
        struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+       if (mdp4_kms->blank_cursor_iova)
+               msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id);
+       if (mdp4_kms->blank_cursor_bo)
+               drm_gem_object_unreference(mdp4_kms->blank_cursor_bo);
        kfree(mdp4_kms);
 }
 
@@ -372,6 +376,23 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev)
                goto fail;
        }
 
+       mutex_lock(&dev->struct_mutex);
+       mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC);
+       mutex_unlock(&dev->struct_mutex);
+       if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
+               ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
+               dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
+               mdp4_kms->blank_cursor_bo = NULL;
+               goto fail;
+       }
+
+       ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id,
+                       &mdp4_kms->blank_cursor_iova);
+       if (ret) {
+               dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
+               goto fail;
+       }
+
        return kms;
 
 fail:
index 66a4d31..715520c 100644 (file)
@@ -44,6 +44,10 @@ struct mdp4_kms {
        struct clk *lut_clk;
 
        struct mdp_irq error_handler;
+
+       /* empty/blank cursor bo to use when cursor is "disabled" */
+       struct drm_gem_object *blank_cursor_bo;
+       uint32_t blank_cursor_iova;
 };
 #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
 
index 353d494..f2b985b 100644 (file)
@@ -71,11 +71,11 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms)
 
        VERB("status=%08x", status);
 
+       mdp_dispatch_irqs(mdp_kms, status);
+
        for (id = 0; id < priv->num_crtcs; id++)
                if (status & mdp5_crtc_vblank(priv->crtcs[id]))
                        drm_handle_vblank(dev, id);
-
-       mdp_dispatch_irqs(mdp_kms, status);
 }
 
 irqreturn_t mdp5_irq(struct msm_kms *kms)
index 6c6d7d4..a752ab8 100644 (file)
@@ -62,11 +62,8 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
        dma_addr_t paddr;
        int ret, size;
 
-       /* only doing ARGB32 since this is what is needed to alpha-blend
-        * with video overlays:
-        */
        sizes->surface_bpp = 32;
-       sizes->surface_depth = 32;
+       sizes->surface_depth = 24;
 
        DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
                        sizes->surface_height, sizes->surface_bpp,
index 3da8264..bb8026d 100644 (file)
@@ -118,8 +118,10 @@ static void put_pages(struct drm_gem_object *obj)
 
                if (iommu_present(&platform_bus_type))
                        drm_gem_put_pages(obj, msm_obj->pages, true, false);
-               else
+               else {
                        drm_mm_remove_node(msm_obj->vram_node);
+                       drm_free_large(msm_obj->pages);
+               }
 
                msm_obj->pages = NULL;
        }
index 36c717a..edb871d 100644 (file)
@@ -312,7 +312,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc)
        struct drm_device *drm = crtc->dev;
        struct drm_plane *plane;
 
-       list_for_each_entry(plane, &drm->mode_config.plane_list, head) {
+       drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) {
                if (plane->crtc == crtc) {
                        tegra_plane_disable(plane);
                        plane->crtc = NULL;
index 931490b..87df0b3 100644 (file)
@@ -1214,14 +1214,36 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
                SVGA3dCmdSurfaceDMA dma;
        } *cmd;
        int ret;
+       SVGA3dCmdSurfaceDMASuffix *suffix;
+       uint32_t bo_size;
 
        cmd = container_of(header, struct vmw_dma_cmd, header);
+       suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma +
+                                              header->size - sizeof(*suffix));
+
+       /* Make sure device and verifier stays in sync. */
+       if (unlikely(suffix->suffixSize != sizeof(*suffix))) {
+               DRM_ERROR("Invalid DMA suffix size.\n");
+               return -EINVAL;
+       }
+
        ret = vmw_translate_guest_ptr(dev_priv, sw_context,
                                      &cmd->dma.guest.ptr,
                                      &vmw_bo);
        if (unlikely(ret != 0))
                return ret;
 
+       /* Make sure DMA doesn't cross BO boundaries. */
+       bo_size = vmw_bo->base.num_pages * PAGE_SIZE;
+       if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) {
+               DRM_ERROR("Invalid DMA offset.\n");
+               return -EINVAL;
+       }
+
+       bo_size -= cmd->dma.guest.ptr.offset;
+       if (unlikely(suffix->maximumOffset > bo_size))
+               suffix->maximumOffset = bo_size;
+
        ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
                                user_surface_converter, &cmd->dma.host.sid,
                                NULL);
index 6d02e3b..d76f0b7 100644 (file)
@@ -365,12 +365,12 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
                if (cpu_has_tjmax(c))
                        dev_warn(dev, "Unable to read TjMax from CPU %u\n", id);
        } else {
-               val = (eax >> 16) & 0x7f;
+               val = (eax >> 16) & 0xff;
                /*
                 * If the TjMax is not plausible, an assumption
                 * will be used
                 */
-               if (val >= 85) {
+               if (val) {
                        dev_dbg(dev, "TjMax is %d degrees C\n", val);
                        return val * 1000;
                }
index d4e8983..23f38cf 100644 (file)
@@ -1,10 +1,10 @@
 config INFINIBAND_CXGB4
-       tristate "Chelsio T4 RDMA Driver"
+       tristate "Chelsio T4/T5 RDMA Driver"
        depends on CHELSIO_T4 && INET && (IPV6 || IPV6=n)
        select GENERIC_ALLOCATOR
        ---help---
-         This is an iWARP/RDMA driver for the Chelsio T4 1GbE and
-         10GbE adapters.
+         This is an iWARP/RDMA driver for the Chelsio T4 and T5
+         1GbE, 10GbE adapters and T5 40GbE adapter.
 
          For general information about Chelsio and our products, visit
          our website at <http://www.chelsio.com>.
index 185452a..1f863a9 100644 (file)
@@ -587,6 +587,10 @@ static int send_connect(struct c4iw_ep *ep)
                opt2 |= SACK_EN(1);
        if (wscale && enable_tcp_window_scaling)
                opt2 |= WND_SCALE_EN(1);
+       if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
+               opt2 |= T5_OPT_2_VALID;
+               opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
+       }
        t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure);
 
        if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) {
@@ -996,7 +1000,7 @@ static void close_complete_upcall(struct c4iw_ep *ep, int status)
 static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp)
 {
        PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
-       state_set(&ep->com, ABORTING);
+       __state_set(&ep->com, ABORTING);
        set_bit(ABORT_CONN, &ep->com.history);
        return send_abort(ep, skb, gfp);
 }
@@ -1154,7 +1158,7 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits)
        return credits;
 }
 
-static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
+static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
 {
        struct mpa_message *mpa;
        struct mpa_v2_conn_params *mpa_v2_params;
@@ -1164,6 +1168,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
        struct c4iw_qp_attributes attrs;
        enum c4iw_qp_attr_mask mask;
        int err;
+       int disconnect = 0;
 
        PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
 
@@ -1173,7 +1178,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
         * will abort the connection.
         */
        if (stop_ep_timer(ep))
-               return;
+               return 0;
 
        /*
         * If we get more than the supported amount of private data
@@ -1195,7 +1200,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
         * if we don't even have the mpa message, then bail.
         */
        if (ep->mpa_pkt_len < sizeof(*mpa))
-               return;
+               return 0;
        mpa = (struct mpa_message *) ep->mpa_pkt;
 
        /* Validate MPA header. */
@@ -1235,7 +1240,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
         * We'll continue process when more data arrives.
         */
        if (ep->mpa_pkt_len < (sizeof(*mpa) + plen))
-               return;
+               return 0;
 
        if (mpa->flags & MPA_REJECT) {
                err = -ECONNREFUSED;
@@ -1337,9 +1342,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
                attrs.layer_etype = LAYER_MPA | DDP_LLP;
                attrs.ecode = MPA_NOMATCH_RTR;
                attrs.next_state = C4IW_QP_STATE_TERMINATE;
+               attrs.send_term = 1;
                err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
-                               C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
+                               C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
                err = -ENOMEM;
+               disconnect = 1;
                goto out;
        }
 
@@ -1355,9 +1362,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
                attrs.layer_etype = LAYER_MPA | DDP_LLP;
                attrs.ecode = MPA_INSUFF_IRD;
                attrs.next_state = C4IW_QP_STATE_TERMINATE;
+               attrs.send_term = 1;
                err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
-                               C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
+                               C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
                err = -ENOMEM;
+               disconnect = 1;
                goto out;
        }
        goto out;
@@ -1366,7 +1375,7 @@ err:
        send_abort(ep, skb, GFP_KERNEL);
 out:
        connect_reply_upcall(ep, err);
-       return;
+       return disconnect;
 }
 
 static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
@@ -1524,6 +1533,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
        unsigned int tid = GET_TID(hdr);
        struct tid_info *t = dev->rdev.lldi.tids;
        __u8 status = hdr->status;
+       int disconnect = 0;
 
        ep = lookup_tid(t, tid);
        if (!ep)
@@ -1539,7 +1549,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
        switch (ep->com.state) {
        case MPA_REQ_SENT:
                ep->rcv_seq += dlen;
-               process_mpa_reply(ep, skb);
+               disconnect = process_mpa_reply(ep, skb);
                break;
        case MPA_REQ_WAIT:
                ep->rcv_seq += dlen;
@@ -1555,13 +1565,16 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb)
                               ep->com.state, ep->hwtid, status);
                attrs.next_state = C4IW_QP_STATE_TERMINATE;
                c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
-                              C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
+                              C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
+               disconnect = 1;
                break;
        }
        default:
                break;
        }
        mutex_unlock(&ep->com.mutex);
+       if (disconnect)
+               c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
        return 0;
 }
 
@@ -2009,6 +2022,10 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb,
                if (tcph->ece && tcph->cwr)
                        opt2 |= CCTRL_ECN(1);
        }
+       if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) {
+               opt2 |= T5_OPT_2_VALID;
+               opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE);
+       }
 
        rpl = cplhdr(skb);
        INIT_TP_WR(rpl, ep->hwtid);
@@ -3482,9 +3499,9 @@ static void process_timeout(struct c4iw_ep *ep)
                        __func__, ep, ep->hwtid, ep->com.state);
                abort = 0;
        }
-       mutex_unlock(&ep->com.mutex);
        if (abort)
                abort_connection(ep, NULL, GFP_KERNEL);
+       mutex_unlock(&ep->com.mutex);
        c4iw_put_ep(&ep->com);
 }
 
index 7b8c580..7474b49 100644 (file)
@@ -435,6 +435,7 @@ struct c4iw_qp_attributes {
        u8 ecode;
        u16 sq_db_inc;
        u16 rq_db_inc;
+       u8 send_term;
 };
 
 struct c4iw_qp {
index 7b5114c..086f62f 100644 (file)
@@ -1388,11 +1388,12 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
                        qhp->attr.layer_etype = attrs->layer_etype;
                        qhp->attr.ecode = attrs->ecode;
                        ep = qhp->ep;
-                       disconnect = 1;
-                       c4iw_get_ep(&qhp->ep->com);
-                       if (!internal)
+                       if (!internal) {
+                               c4iw_get_ep(&qhp->ep->com);
                                terminate = 1;
-                       else {
+                               disconnect = 1;
+                       } else {
+                               terminate = qhp->attr.send_term;
                                ret = rdma_fini(rhp, qhp, ep);
                                if (ret)
                                        goto err;
@@ -1776,11 +1777,15 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        /*
         * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for
         * ringing the queue db when we're in DB_FULL mode.
+        * Only allow this on T4 devices.
         */
        attrs.sq_db_inc = attr->sq_psn;
        attrs.rq_db_inc = attr->rq_psn;
        mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0;
        mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0;
+       if (is_t5(to_c4iw_qp(ibqp)->rhp->rdev.lldi.adapter_type) &&
+           (mask & (C4IW_QP_ATTR_SQ_DB|C4IW_QP_ATTR_RQ_DB)))
+               return -EINVAL;
 
        return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0);
 }
index dc193c2..6121ca0 100644 (file)
@@ -836,4 +836,18 @@ struct ulptx_idata {
 #define V_RX_DACK_CHANGE(x) ((x) << S_RX_DACK_CHANGE)
 #define F_RX_DACK_CHANGE    V_RX_DACK_CHANGE(1U)
 
+enum {                     /* TCP congestion control algorithms */
+       CONG_ALG_RENO,
+       CONG_ALG_TAHOE,
+       CONG_ALG_NEWRENO,
+       CONG_ALG_HIGHSPEED
+};
+
+#define S_CONG_CNTRL    14
+#define M_CONG_CNTRL    0x3
+#define V_CONG_CNTRL(x) ((x) << S_CONG_CNTRL)
+#define G_CONG_CNTRL(x) (((x) >> S_CONG_CNTRL) & M_CONG_CNTRL)
+
+#define T5_OPT_2_VALID       (1 << 31)
+
 #endif /* _T4FW_RI_API_H_ */
index 1bf4a71..9380be7 100644 (file)
@@ -2488,6 +2488,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio)
 
                } else {
                        inc_hit_counter(cache, bio);
+                       pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds);
 
                        if (bio_data_dir(bio) == WRITE && writethrough_mode(&cache->features) &&
                            !is_dirty(cache, lookup_result.cblock))
index 53728be..13abade 100644 (file)
@@ -232,6 +232,13 @@ struct thin_c {
        struct bio_list deferred_bio_list;
        struct bio_list retry_on_resume_list;
        struct rb_root sort_bio_list; /* sorted list of deferred bios */
+
+       /*
+        * Ensures the thin is not destroyed until the worker has finished
+        * iterating the active_thins list.
+        */
+       atomic_t refcount;
+       struct completion can_destroy;
 };
 
 /*----------------------------------------------------------------*/
@@ -1486,6 +1493,45 @@ static void process_thin_deferred_bios(struct thin_c *tc)
        blk_finish_plug(&plug);
 }
 
+static void thin_get(struct thin_c *tc);
+static void thin_put(struct thin_c *tc);
+
+/*
+ * We can't hold rcu_read_lock() around code that can block.  So we
+ * find a thin with the rcu lock held; bump a refcount; then drop
+ * the lock.
+ */
+static struct thin_c *get_first_thin(struct pool *pool)
+{
+       struct thin_c *tc = NULL;
+
+       rcu_read_lock();
+       if (!list_empty(&pool->active_thins)) {
+               tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list);
+               thin_get(tc);
+       }
+       rcu_read_unlock();
+
+       return tc;
+}
+
+static struct thin_c *get_next_thin(struct pool *pool, struct thin_c *tc)
+{
+       struct thin_c *old_tc = tc;
+
+       rcu_read_lock();
+       list_for_each_entry_continue_rcu(tc, &pool->active_thins, list) {
+               thin_get(tc);
+               thin_put(old_tc);
+               rcu_read_unlock();
+               return tc;
+       }
+       thin_put(old_tc);
+       rcu_read_unlock();
+
+       return NULL;
+}
+
 static void process_deferred_bios(struct pool *pool)
 {
        unsigned long flags;
@@ -1493,10 +1539,11 @@ static void process_deferred_bios(struct pool *pool)
        struct bio_list bios;
        struct thin_c *tc;
 
-       rcu_read_lock();
-       list_for_each_entry_rcu(tc, &pool->active_thins, list)
+       tc = get_first_thin(pool);
+       while (tc) {
                process_thin_deferred_bios(tc);
-       rcu_read_unlock();
+               tc = get_next_thin(pool, tc);
+       }
 
        /*
         * If there are any deferred flush bios, we must commit
@@ -1578,7 +1625,7 @@ static void noflush_work(struct thin_c *tc, void (*fn)(struct work_struct *))
 {
        struct noflush_work w;
 
-       INIT_WORK(&w.worker, fn);
+       INIT_WORK_ONSTACK(&w.worker, fn);
        w.tc = tc;
        atomic_set(&w.complete, 0);
        init_waitqueue_head(&w.wait);
@@ -3061,11 +3108,25 @@ static struct target_type pool_target = {
 /*----------------------------------------------------------------
  * Thin target methods
  *--------------------------------------------------------------*/
+static void thin_get(struct thin_c *tc)
+{
+       atomic_inc(&tc->refcount);
+}
+
+static void thin_put(struct thin_c *tc)
+{
+       if (atomic_dec_and_test(&tc->refcount))
+               complete(&tc->can_destroy);
+}
+
 static void thin_dtr(struct dm_target *ti)
 {
        struct thin_c *tc = ti->private;
        unsigned long flags;
 
+       thin_put(tc);
+       wait_for_completion(&tc->can_destroy);
+
        spin_lock_irqsave(&tc->pool->lock, flags);
        list_del_rcu(&tc->list);
        spin_unlock_irqrestore(&tc->pool->lock, flags);
@@ -3101,6 +3162,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
        struct thin_c *tc;
        struct dm_dev *pool_dev, *origin_dev;
        struct mapped_device *pool_md;
+       unsigned long flags;
 
        mutex_lock(&dm_thin_pool_table.mutex);
 
@@ -3191,9 +3253,12 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        mutex_unlock(&dm_thin_pool_table.mutex);
 
-       spin_lock(&tc->pool->lock);
+       atomic_set(&tc->refcount, 1);
+       init_completion(&tc->can_destroy);
+
+       spin_lock_irqsave(&tc->pool->lock, flags);
        list_add_tail_rcu(&tc->list, &tc->pool->active_thins);
-       spin_unlock(&tc->pool->lock);
+       spin_unlock_irqrestore(&tc->pool->lock, flags);
        /*
         * This synchronize_rcu() call is needed here otherwise we risk a
         * wake_worker() call finding no bios to process (because the newly
index 796007a..7a7bab8 100644 (file)
@@ -330,15 +330,17 @@ test_block_hash:
                                return r;
                        }
                }
-
                todo = 1 << v->data_dev_block_bits;
-               while (io->iter.bi_size) {
+               do {
                        u8 *page;
+                       unsigned len;
                        struct bio_vec bv = bio_iter_iovec(bio, io->iter);
 
                        page = kmap_atomic(bv.bv_page);
-                       r = crypto_shash_update(desc, page + bv.bv_offset,
-                                               bv.bv_len);
+                       len = bv.bv_len;
+                       if (likely(len >= todo))
+                               len = todo;
+                       r = crypto_shash_update(desc, page + bv.bv_offset, len);
                        kunmap_atomic(page);
 
                        if (r < 0) {
@@ -346,8 +348,9 @@ test_block_hash:
                                return r;
                        }
 
-                       bio_advance_iter(bio, &io->iter, bv.bv_len);
-               }
+                       bio_advance_iter(bio, &io->iter, len);
+                       todo -= len;
+               } while (todo);
 
                if (!v->version) {
                        r = crypto_shash_update(desc, v->salt, v->salt_size);
index 9bcf2cf..5aeb894 100644 (file)
@@ -364,7 +364,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 
                memset(r, 0, sizeof(*r));
                /*
-                * Get optional "interrupts-names" property to add a name
+                * Get optional "interrupt-names" property to add a name
                 * to the resource.
                 */
                of_property_read_string_index(dev, "interrupt-names", index,
@@ -379,6 +379,32 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
 }
 EXPORT_SYMBOL_GPL(of_irq_to_resource);
 
+/**
+ * of_irq_get - Decode a node's IRQ and return it as a Linux irq number
+ * @dev: pointer to device tree node
+ * @index: zero-based index of the irq
+ *
+ * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
+ * is not yet created.
+ *
+ */
+int of_irq_get(struct device_node *dev, int index)
+{
+       int rc;
+       struct of_phandle_args oirq;
+       struct irq_domain *domain;
+
+       rc = of_irq_parse_one(dev, index, &oirq);
+       if (rc)
+               return rc;
+
+       domain = irq_find_host(oirq.np);
+       if (!domain)
+               return -EPROBE_DEFER;
+
+       return irq_create_of_mapping(&oirq);
+}
+
 /**
  * of_irq_count - Count the number of IRQs a node uses
  * @dev: pointer to device tree node
index 404d1da..bd47fbc 100644 (file)
@@ -168,7 +168,9 @@ struct platform_device *of_device_alloc(struct device_node *np,
                        rc = of_address_to_resource(np, i, res);
                        WARN_ON(rc);
                }
-               WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
+               if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
+                       pr_debug("not all legacy IRQ resources mapped for %s\n",
+                                np->name);
        }
 
        dev->dev.of_node = of_node_get(np);
index ae44500..fe70b86 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -427,6 +428,36 @@ static void __init of_selftest_match_node(void)
        }
 }
 
+static void __init of_selftest_platform_populate(void)
+{
+       int irq;
+       struct device_node *np;
+       struct platform_device *pdev;
+
+       np = of_find_node_by_path("/testcase-data");
+       of_platform_populate(np, of_default_bus_match_table, NULL, NULL);
+
+       /* Test that a missing irq domain returns -EPROBE_DEFER */
+       np = of_find_node_by_path("/testcase-data/testcase-device1");
+       pdev = of_find_device_by_node(np);
+       if (!pdev)
+               selftest(0, "device 1 creation failed\n");
+       irq = platform_get_irq(pdev, 0);
+       if (irq != -EPROBE_DEFER)
+               selftest(0, "device deferred probe failed - %d\n", irq);
+
+       /* Test that a parsing failure does not return -EPROBE_DEFER */
+       np = of_find_node_by_path("/testcase-data/testcase-device2");
+       pdev = of_find_device_by_node(np);
+       if (!pdev)
+               selftest(0, "device 2 creation failed\n");
+       irq = platform_get_irq(pdev, 0);
+       if (irq >= 0 || irq == -EPROBE_DEFER)
+               selftest(0, "device parsing error failed - %d\n", irq);
+
+       selftest(1, "passed");
+}
+
 static int __init of_selftest(void)
 {
        struct device_node *np;
@@ -445,6 +476,7 @@ static int __init of_selftest(void)
        of_selftest_parse_interrupts();
        of_selftest_parse_interrupts_extended();
        of_selftest_match_node();
+       of_selftest_platform_populate();
        pr_info("end of selftest - %i passed, %i failed\n",
                selftest_results.passed, selftest_results.failed);
        return 0;
index c843720..da4695f 100644 (file)
                                                      <&test_intmap1 1 2>;
                        };
                };
+
+               testcase-device1 {
+                       compatible = "testcase-device";
+                       interrupt-parent = <&test_intc0>;
+                       interrupts = <1>;
+               };
+
+               testcase-device2 {
+                       compatible = "testcase-device";
+                       interrupt-parent = <&test_intc2>;
+                       interrupts = <1>; /* invalid specifier - too short */
+               };
        };
+
 };
index 92ed4b2..c862f9c 100644 (file)
@@ -64,7 +64,6 @@ struct as3722_pin_function {
 };
 
 struct as3722_gpio_pin_control {
-       bool enable_gpio_invert;
        unsigned mode_prop;
        int io_function;
 };
@@ -320,10 +319,8 @@ static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev,
                return mode;
        }
 
-       if (as_pci->gpio_control[offset].enable_gpio_invert)
-               mode |= AS3722_GPIO_INV;
-
-       return as3722_write(as3722, AS3722_GPIOn_CONTROL_REG(offset), mode);
+       return as3722_update_bits(as3722, AS3722_GPIOn_CONTROL_REG(offset),
+                               AS3722_GPIO_MODE_MASK, mode);
 }
 
 static const struct pinmux_ops as3722_pinmux_ops = {
@@ -496,10 +493,18 @@ static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset,
 {
        struct as3722_pctrl_info *as_pci = to_as_pci(chip);
        struct as3722 *as3722 = as_pci->as3722;
-       int en_invert = as_pci->gpio_control[offset].enable_gpio_invert;
+       int en_invert;
        u32 val;
        int ret;
 
+       ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val);
+       if (ret < 0) {
+               dev_err(as_pci->dev,
+                       "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
+               return;
+       }
+       en_invert = !!(val & AS3722_GPIO_INV);
+
        if (value)
                val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset);
        else
index 81075f2..2960557 100644 (file)
@@ -810,6 +810,7 @@ static const struct pinconf_ops pcs_pinconf_ops = {
 static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
                unsigned pin_pos)
 {
+       struct pcs_soc_data *pcs_soc = &pcs->socdata;
        struct pinctrl_pin_desc *pin;
        struct pcs_name *pn;
        int i;
@@ -821,6 +822,18 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,
                return -ENOMEM;
        }
 
+       if (pcs_soc->irq_enable_mask) {
+               unsigned val;
+
+               val = pcs->read(pcs->base + offset);
+               if (val & pcs_soc->irq_enable_mask) {
+                       dev_dbg(pcs->dev, "irq enabled at boot for pin at %lx (%x), clearing\n",
+                               (unsigned long)pcs->res->start + offset, val);
+                       val &= ~pcs_soc->irq_enable_mask;
+                       pcs->write(val, pcs->base + offset);
+               }
+       }
+
        pin = &pcs->pins.pa[i];
        pn = &pcs->names[i];
        sprintf(pn->name, "%lx.%d",
index c5e0f69..26ca685 100644 (file)
@@ -629,9 +629,8 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl,
         */
        for (i = 0; i < state->pinfuncgrpcnt; i++) {
                const struct tb10x_pinfuncgrp *pfg = &state->pingroups[i];
-               unsigned int port = pfg->port;
                unsigned int mode = pfg->mode;
-               int j;
+               int j, port = pfg->port;
 
                /*
                 * Skip pin groups which are always mapped and don't need
index 4809371..f5cd3f9 100644 (file)
@@ -4794,8 +4794,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
                FN_MSIOF0_SCK_B, 0,
                /* IP5_23_21 [3] */
                FN_WE1_N, FN_IERX, FN_CAN1_RX, FN_VI1_G4,
-               FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B,
-               FN_IERX_C, 0,
+               FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B, FN_IERX_C,
                /* IP5_20_18 [3] */
                FN_WE0_N, FN_IECLK, FN_CAN_CLK,
                FN_VI2_VSYNC_N, FN_SCIFA0_TXD_B, FN_VI2_VSYNC_N_B, 0, 0,
index 5186d70..7868bf3 100644 (file)
@@ -5288,7 +5288,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
                /* SEL_SCIF3 [2] */
                FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3,
                /* SEL_IEB [2] */
-               FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2,
+               FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0,
                /* SEL_MMC [1] */
                FN_SEL_MMC_0, FN_SEL_MMC_1,
                /* SEL_SCIF5 [1] */
index 9f611cb..c31aa07 100644 (file)
@@ -83,8 +83,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
 {
        struct acpi_device *acpi_dev;
        acpi_handle handle;
-       struct acpi_buffer buffer;
-       int ret;
+       int ret = 0;
 
        pnp_dbg(&dev->dev, "set resources\n");
 
@@ -97,19 +96,26 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
        if (WARN_ON_ONCE(acpi_dev != dev->data))
                dev->data = acpi_dev;
 
-       ret = pnpacpi_build_resource_template(dev, &buffer);
-       if (ret)
-               return ret;
-       ret = pnpacpi_encode_resources(dev, &buffer);
-       if (ret) {
+       if (acpi_has_method(handle, METHOD_NAME__SRS)) {
+               struct acpi_buffer buffer;
+
+               ret = pnpacpi_build_resource_template(dev, &buffer);
+               if (ret)
+                       return ret;
+
+               ret = pnpacpi_encode_resources(dev, &buffer);
+               if (!ret) {
+                       acpi_status status;
+
+                       status = acpi_set_current_resources(handle, &buffer);
+                       if (ACPI_FAILURE(status))
+                               ret = -EIO;
+               }
                kfree(buffer.pointer);
-               return ret;
        }
-       if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
-               ret = -EINVAL;
-       else if (acpi_bus_power_manageable(handle))
+       if (!ret && acpi_bus_power_manageable(handle))
                ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
-       kfree(buffer.pointer);
+
        return ret;
 }
 
@@ -117,7 +123,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
 {
        struct acpi_device *acpi_dev;
        acpi_handle handle;
-       int ret;
+       acpi_status status;
 
        dev_dbg(&dev->dev, "disable resources\n");
 
@@ -128,13 +134,15 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
        }
 
        /* acpi_unregister_gsi(pnp_irq(dev, 0)); */
-       ret = 0;
        if (acpi_bus_power_manageable(handle))
                acpi_bus_set_power(handle, ACPI_STATE_D3_COLD);
-               /* continue even if acpi_bus_set_power() fails */
-       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
-               ret = -ENODEV;
-       return ret;
+
+       /* continue even if acpi_bus_set_power() fails */
+       status = acpi_evaluate_object(handle, "_DIS", NULL, NULL);
+       if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+               return -ENODEV;
+
+       return 0;
 }
 
 #ifdef CONFIG_ACPI_SLEEP
index 3736bc4..ebf0d67 100644 (file)
@@ -335,7 +335,7 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
 }
 #endif
 
-#ifdef CONFIG_X86
+#ifdef CONFIG_PCI
 /* Device IDs of parts that have 32KB MCH space */
 static const unsigned int mch_quirk_devices[] = {
        0x0154, /* Ivy Bridge */
@@ -440,7 +440,7 @@ static struct pnp_fixup pnp_fixups[] = {
 #ifdef CONFIG_AMD_NB
        {"PNP0c01", quirk_amd_mmconfig_area},
 #endif
-#ifdef CONFIG_X86
+#ifdef CONFIG_PCI
        {"PNP0c02", quirk_intel_mch},
 #endif
        {""}
index 9f0ea6c..e3bf885 100644 (file)
@@ -541,18 +541,27 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
 
 static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
 {
-       do {
+       static int ntsm_unsupported;
+
+       while (true) {
                memset(sei, 0, sizeof(*sei));
                sei->request.length = 0x0010;
                sei->request.code = 0x000e;
-               sei->ntsm = ntsm;
+               if (!ntsm_unsupported)
+                       sei->ntsm = ntsm;
 
                if (chsc(sei))
                        break;
 
                if (sei->response.code != 0x0001) {
-                       CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
-                                     sei->response.code);
+                       CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x, ntsm=%llx)\n",
+                                     sei->response.code, sei->ntsm);
+
+                       if (sei->response.code == 3 && sei->ntsm) {
+                               /* Fallback for old firmware. */
+                               ntsm_unsupported = 1;
+                               continue;
+                       }
                        break;
                }
 
@@ -568,7 +577,10 @@ static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
                        CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt);
                        break;
                }
-       } while (sei->u.nt0_area.flags & 0x80);
+
+               if (!(sei->u.nt0_area.flags & 0x80))
+                       break;
+       }
 }
 
 /*
index 12a3de0..a0ed6c7 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -112,6 +112,11 @@ struct kioctx {
 
        struct work_struct      free_work;
 
+       /*
+        * signals when all in-flight requests are done
+        */
+       struct completion *requests_done;
+
        struct {
                /*
                 * This counts the number of available slots in the ringbuffer,
@@ -508,6 +513,10 @@ static void free_ioctx_reqs(struct percpu_ref *ref)
 {
        struct kioctx *ctx = container_of(ref, struct kioctx, reqs);
 
+       /* At this point we know that there are no any in-flight requests */
+       if (ctx->requests_done)
+               complete(ctx->requests_done);
+
        INIT_WORK(&ctx->free_work, free_ioctx);
        schedule_work(&ctx->free_work);
 }
@@ -718,7 +727,8 @@ err:
  *     when the processes owning a context have all exited to encourage
  *     the rapid destruction of the kioctx.
  */
-static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx)
+static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx,
+               struct completion *requests_done)
 {
        if (!atomic_xchg(&ctx->dead, 1)) {
                struct kioctx_table *table;
@@ -747,7 +757,11 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx)
                if (ctx->mmap_size)
                        vm_munmap(ctx->mmap_base, ctx->mmap_size);
 
+               ctx->requests_done = requests_done;
                percpu_ref_kill(&ctx->users);
+       } else {
+               if (requests_done)
+                       complete(requests_done);
        }
 }
 
@@ -809,7 +823,7 @@ void exit_aio(struct mm_struct *mm)
                 */
                ctx->mmap_size = 0;
 
-               kill_ioctx(mm, ctx);
+               kill_ioctx(mm, ctx, NULL);
        }
 }
 
@@ -1185,7 +1199,7 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp)
        if (!IS_ERR(ioctx)) {
                ret = put_user(ioctx->user_id, ctxp);
                if (ret)
-                       kill_ioctx(current->mm, ioctx);
+                       kill_ioctx(current->mm, ioctx, NULL);
                percpu_ref_put(&ioctx->users);
        }
 
@@ -1203,8 +1217,22 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
 {
        struct kioctx *ioctx = lookup_ioctx(ctx);
        if (likely(NULL != ioctx)) {
-               kill_ioctx(current->mm, ioctx);
+               struct completion requests_done =
+                       COMPLETION_INITIALIZER_ONSTACK(requests_done);
+
+               /* Pass requests_done to kill_ioctx() where it can be set
+                * in a thread-safe way. If we try to set it here then we have
+                * a race condition if two io_destroy() called simultaneously.
+                */
+               kill_ioctx(current->mm, ioctx, &requests_done);
                percpu_ref_put(&ioctx->users);
+
+               /* Wait until all IO for the context are done. Otherwise kernel
+                * keep using user-space buffers even if user thinks the context
+                * is destroyed.
+                */
+               wait_for_completion(&requests_done);
+
                return 0;
        }
        pr_debug("EINVAL: io_destroy: invalid context id\n");
@@ -1299,10 +1327,8 @@ rw_common:
                                                &iovec, compat)
                        : aio_setup_single_vector(req, rw, buf, &nr_segs,
                                                  iovec);
-               if (ret)
-                       return ret;
-
-               ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes);
+               if (!ret)
+                       ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes);
                if (ret < 0) {
                        if (iovec != &inline_vec)
                                kfree(iovec);
index d96deb4..94f9ea8 100644 (file)
@@ -50,7 +50,7 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct
 }
 
 #ifndef zero_bytemask
-#define zero_bytemask(mask) (~0ul << __fls(mask) << 1)
+#define zero_bytemask(mask) (~1ul << __fls(mask))
 #endif
 
 #endif /* _ASM_WORD_AT_A_TIME_H */
index 9212b01..ae9504b 100644 (file)
@@ -535,6 +535,7 @@ static inline int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_a
 extern int ftrace_arch_read_dyn_info(char *buf, int size);
 
 extern int skip_trace(unsigned long ip);
+extern void ftrace_module_init(struct module *mod);
 
 extern void ftrace_disable_daemon(void);
 extern void ftrace_enable_daemon(void);
@@ -544,6 +545,7 @@ static inline int ftrace_force_update(void) { return 0; }
 static inline void ftrace_disable_daemon(void) { }
 static inline void ftrace_enable_daemon(void) { }
 static inline void ftrace_release_mod(struct module *mod) {}
+static inline void ftrace_module_init(struct module *mod) {}
 static inline __init int register_ftrace_command(struct ftrace_func_command *cmd)
 {
        return -EINVAL;
index 3f23b44..6404253 100644 (file)
@@ -44,11 +44,16 @@ extern void of_irq_init(const struct of_device_id *matches);
 
 #ifdef CONFIG_OF_IRQ
 extern int of_irq_count(struct device_node *dev);
+extern int of_irq_get(struct device_node *dev, int index);
 #else
 static inline int of_irq_count(struct device_node *dev)
 {
        return 0;
 }
+static inline int of_irq_get(struct device_node *dev, int index)
+{
+       return 0;
+}
 #endif
 
 #if defined(CONFIG_OF)
index 11fd51b..ed0b2c5 100644 (file)
@@ -25,7 +25,7 @@ struct module;
        { (1UL << TAINT_OOT_MODULE),            "O" },          \
        { (1UL << TAINT_FORCED_MODULE),         "F" },          \
        { (1UL << TAINT_CRAP),                  "C" },          \
-       { (1UL << TAINT_UNSIGNED_MODULE),       "X" })
+       { (1UL << TAINT_UNSIGNED_MODULE),       "E" })
 
 TRACE_EVENT(module_load,
 
index d55092c..6b715c0 100644 (file)
@@ -234,6 +234,11 @@ again:
                        goto again;
                }
                timer->base = new_base;
+       } else {
+               if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) {
+                       cpu = this_cpu;
+                       goto again;
+               }
        }
        return new_base;
 }
@@ -569,6 +574,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
 
        cpu_base->expires_next.tv64 = expires_next.tv64;
 
+       /*
+        * If a hang was detected in the last timer interrupt then we
+        * leave the hang delay active in the hardware. We want the
+        * system to make progress. That also prevents the following
+        * scenario:
+        * T1 expires 50ms from now
+        * T2 expires 5s from now
+        *
+        * T1 is removed, so this code is called and would reprogram
+        * the hardware to 5s from now. Any hrtimer_start after that
+        * will not reprogram the hardware due to hang_detected being
+        * set. So we'd effectivly block all timers until the T2 event
+        * fires.
+        */
+       if (cpu_base->hang_detected)
+               return;
+
        if (cpu_base->expires_next.tv64 != KTIME_MAX)
                tick_program_event(cpu_base->expires_next, 1);
 }
index 1186940..079c461 100644 (file)
@@ -815,9 +815,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
                return -EFAULT;
        name[MODULE_NAME_LEN-1] = '\0';
 
-       if (!(flags & O_NONBLOCK))
-               pr_warn("waiting module removal not supported: please upgrade\n");
-
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
 
@@ -3271,6 +3268,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
 
        dynamic_debug_setup(info->debug, info->num_debug);
 
+       /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */
+       ftrace_module_init(mod);
+
        /* Finally it's fully formed, ready to start executing. */
        err = complete_formation(mod, info);
        if (err)
index 87bd529..3bb01a3 100644 (file)
@@ -838,7 +838,7 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
 
        bit = find_last_bit(&mask, BITS_PER_LONG);
 
-       mask = (1 << bit) - 1;
+       mask = (1UL << bit) - 1;
 
        expires_limit = expires_limit & ~(mask);
 
index 1fd4b94..4a54a25 100644 (file)
@@ -4330,16 +4330,11 @@ static void ftrace_init_module(struct module *mod,
        ftrace_process_locs(mod, start, end);
 }
 
-static int ftrace_module_notify_enter(struct notifier_block *self,
-                                     unsigned long val, void *data)
+void ftrace_module_init(struct module *mod)
 {
-       struct module *mod = data;
-
-       if (val == MODULE_STATE_COMING)
-               ftrace_init_module(mod, mod->ftrace_callsites,
-                                  mod->ftrace_callsites +
-                                  mod->num_ftrace_callsites);
-       return 0;
+       ftrace_init_module(mod, mod->ftrace_callsites,
+                          mod->ftrace_callsites +
+                          mod->num_ftrace_callsites);
 }
 
 static int ftrace_module_notify_exit(struct notifier_block *self,
@@ -4353,11 +4348,6 @@ static int ftrace_module_notify_exit(struct notifier_block *self,
        return 0;
 }
 #else
-static int ftrace_module_notify_enter(struct notifier_block *self,
-                                     unsigned long val, void *data)
-{
-       return 0;
-}
 static int ftrace_module_notify_exit(struct notifier_block *self,
                                     unsigned long val, void *data)
 {
@@ -4365,11 +4355,6 @@ static int ftrace_module_notify_exit(struct notifier_block *self,
 }
 #endif /* CONFIG_MODULES */
 
-struct notifier_block ftrace_module_enter_nb = {
-       .notifier_call = ftrace_module_notify_enter,
-       .priority = INT_MAX,    /* Run before anything that can use kprobes */
-};
-
 struct notifier_block ftrace_module_exit_nb = {
        .notifier_call = ftrace_module_notify_exit,
        .priority = INT_MIN,    /* Run after anything that can remove kprobes */
@@ -4403,10 +4388,6 @@ void __init ftrace_init(void)
                                  __start_mcount_loc,
                                  __stop_mcount_loc);
 
-       ret = register_module_notifier(&ftrace_module_enter_nb);
-       if (ret)
-               pr_warning("Failed to register trace ftrace module enter notifier\n");
-
        ret = register_module_notifier(&ftrace_module_exit_nb);
        if (ret)
                pr_warning("Failed to register trace ftrace module exit notifier\n");
index 925f537..4747b47 100644 (file)
@@ -77,7 +77,7 @@ event_triggers_call(struct ftrace_event_file *file, void *rec)
                        data->ops->func(data);
                        continue;
                }
-               filter = rcu_dereference(data->filter);
+               filter = rcu_dereference_sched(data->filter);
                if (filter && !filter_match_preds(filter, rec))
                        continue;
                if (data->cmd_ops->post_trigger) {
index d4224b3..1037a3b 100644 (file)
@@ -81,10 +81,12 @@ struct vm_area_struct *vmacache_find(struct mm_struct *mm, unsigned long addr)
        for (i = 0; i < VMACACHE_SIZE; i++) {
                struct vm_area_struct *vma = current->vmacache[i];
 
-               if (vma && vma->vm_start <= addr && vma->vm_end > addr) {
-                       BUG_ON(vma->vm_mm != mm);
+               if (!vma)
+                       continue;
+               if (WARN_ON_ONCE(vma->vm_mm != mm))
+                       break;
+               if (vma->vm_start <= addr && vma->vm_end > addr)
                        return vma;
-               }
        }
 
        return NULL;
index 248b90a..480bbdd 100644 (file)
@@ -1059,24 +1059,26 @@ static void azx_init_cmd_io(struct azx *chip)
 
        /* reset the corb hw read pointer */
        azx_writew(chip, CORBRP, ICH6_CORBRP_RST);
-       for (timeout = 1000; timeout > 0; timeout--) {
-               if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST)
-                       break;
-               udelay(1);
-       }
-       if (timeout <= 0)
-               dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n",
-                       azx_readw(chip, CORBRP));
+       if (!(chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)) {
+               for (timeout = 1000; timeout > 0; timeout--) {
+                       if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST)
+                               break;
+                       udelay(1);
+               }
+               if (timeout <= 0)
+                       dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n",
+                               azx_readw(chip, CORBRP));
 
-       azx_writew(chip, CORBRP, 0);
-       for (timeout = 1000; timeout > 0; timeout--) {
-               if (azx_readw(chip, CORBRP) == 0)
-                       break;
-               udelay(1);
+               azx_writew(chip, CORBRP, 0);
+               for (timeout = 1000; timeout > 0; timeout--) {
+                       if (azx_readw(chip, CORBRP) == 0)
+                               break;
+                       udelay(1);
+               }
+               if (timeout <= 0)
+                       dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n",
+                               azx_readw(chip, CORBRP));
        }
-       if (timeout <= 0)
-               dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n",
-                       azx_readw(chip, CORBRP));
 
        /* enable corb dma */
        azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN);
index d6bca62..b540ad7 100644 (file)
@@ -249,7 +249,8 @@ enum {
 /* quirks for Nvidia */
 #define AZX_DCAPS_PRESET_NVIDIA \
        (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
-        AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT)
+        AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT |\
+        AZX_DCAPS_CORBRP_SELF_CLEAR)
 
 #define AZX_DCAPS_PRESET_CTHDA \
        (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY)
index ba38b81..4a7cb01 100644 (file)
@@ -189,6 +189,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
 #define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)  /* Take LPIB as delay */
 #define AZX_DCAPS_PM_RUNTIME   (1 << 26)       /* runtime PM support */
 #define AZX_DCAPS_I915_POWERWELL (1 << 27)     /* HSW i915 powerwell support */
+#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)  /* CORBRP clears itself after reset */
 
 /* position fix mode */
 enum {
index c643dfc..c1952c9 100644 (file)
@@ -4621,6 +4621,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
index f500905..2acf82f 100644 (file)
@@ -1018,13 +1018,13 @@ static int alc5623_i2c_probe(struct i2c_client *client,
                dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret);
                return ret;
        }
-       vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
 
        ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2);
        if (ret < 0) {
                dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret);
                return ret;
        }
+       vid2 >>= 8;
 
        if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
                dev_err(&client->dev, "unknown or wrong codec\n");
index 460d355..2213a03 100644 (file)
@@ -1229,8 +1229,10 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
        }
 
        if (cs42l52->pdata.reset_gpio) {
-               ret = gpio_request_one(cs42l52->pdata.reset_gpio,
-                                      GPIOF_OUT_INIT_HIGH, "CS42L52 /RST");
+               ret = devm_gpio_request_one(&i2c_client->dev,
+                                           cs42l52->pdata.reset_gpio,
+                                           GPIOF_OUT_INIT_HIGH,
+                                           "CS42L52 /RST");
                if (ret < 0) {
                        dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n",
                                cs42l52->pdata.reset_gpio, ret);
index 0ee60a1..ae37179 100644 (file)
@@ -1443,8 +1443,10 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client,
        i2c_set_clientdata(i2c_client, cs42l73);
 
        if (cs42l73->pdata.reset_gpio) {
-               ret = gpio_request_one(cs42l73->pdata.reset_gpio,
-                                      GPIOF_OUT_INIT_HIGH, "CS42L73 /RST");
+               ret = devm_gpio_request_one(&i2c_client->dev,
+                                           cs42l73->pdata.reset_gpio,
+                                           GPIOF_OUT_INIT_HIGH,
+                                           "CS42L73 /RST");
                if (ret < 0) {
                        dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n",
                                cs42l73->pdata.reset_gpio, ret);
index b183510..d7349bc 100644 (file)
@@ -1399,7 +1399,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
        }
 
        aic3x_add_widgets(codec);
-       list_add(&aic3x->list, &reset_list);
 
        return 0;
 
@@ -1569,7 +1568,13 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
 
        ret = snd_soc_register_codec(&i2c->dev,
                        &soc_codec_dev_aic3x, &aic3x_dai, 1);
-       return ret;
+
+       if (ret != 0)
+               goto err_gpio;
+
+       list_add(&aic3x->list, &reset_list);
+
+       return 0;
 
 err_gpio:
        if (gpio_is_valid(aic3x->gpio_reset) &&
index b126679..605a10b 100644 (file)
@@ -144,8 +144,8 @@ enum spdif_gainsel {
 
 /* SPDIF Clock register */
 #define STC_SYSCLK_DIV_OFFSET          11
-#define STC_SYSCLK_DIV_MASK            (0x1ff << STC_TXCLK_SRC_OFFSET)
-#define STC_SYSCLK_DIV(x)              ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK)
+#define STC_SYSCLK_DIV_MASK            (0x1ff << STC_SYSCLK_DIV_OFFSET)
+#define STC_SYSCLK_DIV(x)              ((((x) - 1) << STC_SYSCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK)
 #define STC_TXCLK_SRC_OFFSET           8
 #define STC_TXCLK_SRC_MASK             (0x7 << STC_TXCLK_SRC_OFFSET)
 #define STC_TXCLK_SRC_SET(x)           ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK)
index fe8e81a..30ca14a 100644 (file)
@@ -136,7 +136,7 @@ struct sst_module_data {
        enum sst_data_type data_type;   /* type of module data */
 
        u32 size;               /* size in bytes */
-       u32 offset;             /* offset in FW file */
+       int32_t offset;         /* offset in FW file */
        u32 data_offset;        /* offset in ADSP memory space */
        void *data;             /* module data */
 };
index f46bb4d..50e4246 100644 (file)
@@ -617,7 +617,7 @@ static void hsw_notification_work(struct work_struct *work)
        case IPC_POSITION_CHANGED:
                trace_ipc_notification("DSP stream position changed for",
                        stream->reply.stream_hw_id);
-               sst_dsp_inbox_read(hsw->dsp, pos, sizeof(pos));
+               sst_dsp_inbox_read(hsw->dsp, pos, sizeof(*pos));
 
                if (stream->notify_position)
                        stream->notify_position(stream, stream->pdata);
@@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream
                return -EINVAL;
 
        sst_dsp_read(hsw->dsp, volume,
-               stream->reply.volume_register_address[channel], sizeof(volume));
+               stream->reply.volume_register_address[channel],
+               sizeof(*volume));
 
        return 0;
 }
@@ -1609,7 +1610,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
        trace_ipc_request("PM enter Dx state", state);
 
        ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_),
-               dx, sizeof(dx));
+               dx, sizeof(*dx));
        if (ret < 0) {
                dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state);
                return ret;
index be873c1..d32c540 100644 (file)
@@ -1,10 +1,8 @@
 #
 # Jz4740 Platform Support
 #
-snd-soc-jz4740-objs := jz4740-pcm.o
 snd-soc-jz4740-i2s-objs := jz4740-i2s.o
 
-obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o
 obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o
 
 # Jz4740 Machine Support
index 6232b7d..4d0720e 100644 (file)
@@ -258,7 +258,7 @@ static int rsnd_src_init(struct rsnd_mod *mod,
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
 
-       clk_enable(src->clk);
+       clk_prepare_enable(src->clk);
 
        return 0;
 }
@@ -269,7 +269,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
 {
        struct rsnd_src *src = rsnd_mod_to_src(mod);
 
-       clk_disable(src->clk);
+       clk_disable_unprepare(src->clk);
 
        return 0;
 }
index 4b7e206..1d8387c 100644 (file)
@@ -171,7 +171,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi,
        u32 cr;
 
        if (0 == ssi->usrcnt) {
-               clk_enable(ssi->clk);
+               clk_prepare_enable(ssi->clk);
 
                if (rsnd_dai_is_clk_master(rdai)) {
                        if (rsnd_ssi_clk_from_parent(ssi))
@@ -230,7 +230,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi,
                                rsnd_ssi_master_clk_stop(ssi);
                }
 
-               clk_disable(ssi->clk);
+               clk_disable_unprepare(ssi->clk);
        }
 
        dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod));
index c8a780d..7769b0a 100644 (file)
@@ -254,7 +254,6 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
 static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
 {
        struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
-       kfree(data->widget);
        kfree(data->wlist);
        kfree(data);
 }
index 7c43479..a74fba6 100644 (file)
@@ -12,8 +12,8 @@
 char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug";
 
 static const char * const debugfs_known_mountpoints[] = {
-       "/sys/kernel/debug/",
-       "/debug/",
+       "/sys/kernel/debug",
+       "/debug",
        0,
 };
 
index baec7d8..b83184f 100644 (file)
@@ -4344,6 +4344,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
                                              format, len_arg, arg);
                                trace_seq_terminate(&p);
                                trace_seq_puts(s, p.buffer);
+                               trace_seq_destroy(&p);
                                arg = arg->next;
                                break;
                        default:
index 791c539..feab942 100644 (file)
@@ -876,8 +876,8 @@ struct event_filter {
 struct event_filter *pevent_filter_alloc(struct pevent *pevent);
 
 /* for backward compatibility */
-#define FILTER_NONE            PEVENT_ERRNO__FILTER_NOT_FOUND
-#define FILTER_NOEXIST         PEVENT_ERRNO__NO_FILTER
+#define FILTER_NONE            PEVENT_ERRNO__NO_FILTER
+#define FILTER_NOEXIST         PEVENT_ERRNO__FILTER_NOT_FOUND
 #define FILTER_MISS            PEVENT_ERRNO__FILTER_MISS
 #define FILTER_MATCH           PEVENT_ERRNO__FILTER_MATCH
 
index e969233..895edd3 100644 (file)
@@ -589,7 +589,7 @@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
        $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
 
 $(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
-       $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
+       $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
 
 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
        $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
index b602ad9..83bc238 100644 (file)
@@ -23,9 +23,10 @@ static int sample_ustack(struct perf_sample *sample,
 
        sp = (unsigned long) regs[PERF_REG_X86_SP];
 
-       map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
+       map = map_groups__find(&thread->mg, MAP__VARIABLE, (u64) sp);
        if (!map) {
                pr_debug("failed to get stack map\n");
+               free(buf);
                return -1;
        }
 
index 99167bf..60875d5 100644 (file)
@@ -1,4 +1,3 @@
-
 #include <linux/linkage.h>
 
 #define AX      0
@@ -90,3 +89,10 @@ ENTRY(perf_regs_load)
        ret
 ENDPROC(perf_regs_load)
 #endif
+
+/*
+ * We need to provide note.GNU-stack section, saying that we want
+ * NOT executable stack. Otherwise the final linking will assume that
+ * the ELF stack should not be restricted at all and set it RWX.
+ */
+.section .note.GNU-stack,"",@progbits
index ee21fa9..802cf54 100644 (file)
@@ -34,6 +34,14 @@ ifeq ($(ARCH),arm)
   LIBUNWIND_LIBS = -lunwind -lunwind-arm
 endif
 
+# So far there's only x86 libdw unwind support merged in perf.
+# Disable it on all other architectures in case libdw unwind
+# support is detected in system. Add supported architectures
+# to the check.
+ifneq ($(ARCH),x86)
+  NO_LIBDW_DWARF_UNWIND := 1
+endif
+
 ifeq ($(LIBUNWIND_LIBS),)
   NO_LIBUNWIND := 1
 else
@@ -109,6 +117,10 @@ CFLAGS += -Wall
 CFLAGS += -Wextra
 CFLAGS += -std=gnu99
 
+# Enforce a non-executable stack, as we may regress (again) in the future by
+# adding assembler files missing the .GNU-stack linker note.
+LDFLAGS += -Wl,-z,noexecstack
+
 EXTLIBS = -lelf -lpthread -lrt -lm -ldl
 
 ifneq ($(OUTPUT),)
@@ -186,7 +198,10 @@ VF_FEATURE_TESTS =                 \
        stackprotector-all              \
        timerfd                         \
        libunwind-debug-frame           \
-       bionic
+       bionic                          \
+       liberty                         \
+       liberty-z                       \
+       cplus-demangle
 
 # Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features.
 # If in the future we need per-feature checks/flags for features not
@@ -504,7 +519,21 @@ else
 endif
 
 ifeq ($(feature-libbfd), 1)
-  EXTLIBS += -lbfd -lz -liberty
+  EXTLIBS += -lbfd
+
+  # call all detections now so we get correct
+  # status in VF output
+  $(call feature_check,liberty)
+  $(call feature_check,liberty-z)
+  $(call feature_check,cplus-demangle)
+
+  ifeq ($(feature-liberty), 1)
+    EXTLIBS += -liberty
+  else
+    ifeq ($(feature-liberty-z), 1)
+      EXTLIBS += -liberty -lz
+    endif
+  endif
 endif
 
 ifdef NO_DEMANGLE
@@ -515,15 +544,10 @@ else
     CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
   else
     ifneq ($(feature-libbfd), 1)
-      $(call feature_check,liberty)
-      ifeq ($(feature-liberty), 1)
-        EXTLIBS += -lbfd -liberty
-      else
-        $(call feature_check,liberty-z)
-        ifeq ($(feature-liberty-z), 1)
-          EXTLIBS += -lbfd -liberty -lz
-        else
-          $(call feature_check,cplus-demangle)
+      ifneq ($(feature-liberty), 1)
+        ifneq ($(feature-liberty-z), 1)
+          # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT
+          # or any of 'bfd iberty z' trinity
           ifeq ($(feature-cplus-demangle), 1)
             EXTLIBS += -liberty
             CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
index 5daeae1..2f92d6e 100644 (file)
@@ -46,6 +46,7 @@ make_install_man    := install-man
 make_install_html   := install-html
 make_install_info   := install-info
 make_install_pdf    := install-pdf
+make_static         := LDFLAGS=-static
 
 # all the NO_* variable combined
 make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
@@ -87,6 +88,7 @@ run += make_install_bin
 # run += make_install_info
 # run += make_install_pdf
 run += make_minimal
+run += make_static
 
 ifneq ($(call has,ctags),)
 run += make_tags
index a53cd0b..27c2a5e 100644 (file)
@@ -717,7 +717,7 @@ static char *get_kernel_version(const char *root_dir)
 }
 
 static int map_groups__set_modules_path_dir(struct map_groups *mg,
-                               const char *dir_name)
+                               const char *dir_name, int depth)
 {
        struct dirent *dent;
        DIR *dir = opendir(dir_name);
@@ -742,7 +742,15 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg,
                            !strcmp(dent->d_name, ".."))
                                continue;
 
-                       ret = map_groups__set_modules_path_dir(mg, path);
+                       /* Do not follow top-level source and build symlinks */
+                       if (depth == 0) {
+                               if (!strcmp(dent->d_name, "source") ||
+                                   !strcmp(dent->d_name, "build"))
+                                       continue;
+                       }
+
+                       ret = map_groups__set_modules_path_dir(mg, path,
+                                                              depth + 1);
                        if (ret < 0)
                                goto out;
                } else {
@@ -786,11 +794,11 @@ static int machine__set_modules_path(struct machine *machine)
        if (!version)
                return -1;
 
-       snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
+       snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s",
                 machine->root_dir, version);
        free(version);
 
-       return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
+       return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0);
 }
 
 static int machine__create_module(void *arg, const char *name, u64 start)
index 47b2983..56ff9be 100644 (file)
@@ -548,11 +548,10 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
        u32 val;
        u32 *reg;
 
-       offset >>= 1;
        reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg,
-                                 vcpu->vcpu_id, offset);
+                                 vcpu->vcpu_id, offset >> 1);
 
-       if (offset & 2)
+       if (offset & 4)
                val = *reg >> 16;
        else
                val = *reg & 0xffff;
@@ -561,13 +560,13 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu,
        vgic_reg_access(mmio, &val, offset,
                        ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
        if (mmio->is_write) {
-               if (offset < 4) {
+               if (offset < 8) {
                        *reg = ~0U; /* Force PPIs/SGIs to 1 */
                        return false;
                }
 
                val = vgic_cfg_compress(val);
-               if (offset & 2) {
+               if (offset & 4) {
                        *reg &= 0xffff;
                        *reg |= val << 16;
                } else {
@@ -916,6 +915,7 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg)
        case 0:
                if (!target_cpus)
                        return;
+               break;
 
        case 1:
                target_cpus = ((1 << nrcpus) - 1) & ~(1 << vcpu_id) & 0xff;
@@ -1667,10 +1667,11 @@ static int vgic_ioaddr_assign(struct kvm *kvm, phys_addr_t *ioaddr,
        if (addr + size < addr)
                return -EINVAL;
 
+       *ioaddr = addr;
        ret = vgic_ioaddr_overlap(kvm);
        if (ret)
-               return ret;
-       *ioaddr = addr;
+               *ioaddr = VGIC_ADDR_UNDEF;
+
        return ret;
 }
 
index 8db4370..bf06577 100644 (file)
@@ -395,7 +395,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm,
        if (dev->entries_nr == 0)
                return r;
 
-       r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr);
+       r = pci_enable_msix_exact(dev->dev,
+                                 dev->host_msix_entries, dev->entries_nr);
        if (r)
                return r;
 
index 10df100..06e6401 100644 (file)
@@ -101,7 +101,7 @@ static void async_pf_execute(struct work_struct *work)
        if (waitqueue_active(&vcpu->wq))
                wake_up_interruptible(&vcpu->wq);
 
-       mmdrop(mm);
+       mmput(mm);
        kvm_put_kvm(vcpu->kvm);
 }
 
@@ -118,7 +118,7 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu)
                flush_work(&work->work);
 #else
                if (cancel_work_sync(&work->work)) {
-                       mmdrop(work->mm);
+                       mmput(work->mm);
                        kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */
                        kmem_cache_free(async_pf_cache, work);
                }
@@ -183,7 +183,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva,
        work->addr = hva;
        work->arch = *arch;
        work->mm = current->mm;
-       atomic_inc(&work->mm->mm_count);
+       atomic_inc(&work->mm->mm_users);
        kvm_get_kvm(work->vcpu->kvm);
 
        /* this can't really happen otherwise gfn_to_pfn_async
@@ -201,7 +201,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva,
        return 1;
 retry_sync:
        kvm_put_kvm(work->vcpu->kvm);
-       mmdrop(work->mm);
+       mmput(work->mm);
        kmem_cache_free(async_pf_cache, work);
        return 0;
 }