]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'errseq-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Apr 2018 23:53:40 +0000 (16:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Apr 2018 23:53:40 +0000 (16:53 -0700)
Pull errseq infrastructure fix from Jeff Layton:
 "The PostgreSQL developers recently had a spirited discussion about the
  writeback error handling in Linux, and reached out to us about a
  behavoir change to the code that bit them when the errseq_t changes
  were merged.

  When we changed to using errseq_t for tracking writeback errors, we
  lost the ability for an application to see a writeback error that
  occurred before the open on which the fsync was issued. This was
  problematic for PostgreSQL which offloads fsync calls to a completely
  separate process from the DB writers.

  This patch restores that ability. If the errseq_t value in the inode
  does not have the SEEN flag set, then we just return 0 for the sample.
  That ensures that any recorded error is always delivered at least
  once.

  Note that we might still lose the error if the inode gets evicted from
  the cache before anything can reopen it, but that was the case before
  errseq_t was merged. At LSF/MM we had some discussion about keeping
  inodes with unreported writeback errors around in the cache for longer
  (possibly indefinitely), but that's really a separate problem"

* tag 'errseq-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux:
  errseq: Always report a writeback error once

271 files changed:
Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt
Documentation/devicetree/bindings/serial/mvebu-uart.txt
Documentation/devicetree/bindings/serial/renesas,sci-serial.txt
Documentation/devicetree/bindings/usb/usb-xhci.txt
Documentation/driver-api/firmware/request_firmware.rst
Documentation/driver-api/infrastructure.rst
Documentation/driver-api/usb/typec.rst
Documentation/i2c/dev-interface
Documentation/ioctl/ioctl-number.txt
Documentation/networking/ip-sysctl.txt
Documentation/power/suspend-and-cpuhotplug.txt
Documentation/process/magic-number.rst
Documentation/trace/ftrace.rst
Documentation/virtual/kvm/api.txt
Documentation/virtual/kvm/arm/psci.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/arm/boot/dts/gemini-nas4220b.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/configs/gemini_defconfig
arch/arm/configs/socfpga_defconfig
arch/arm/include/asm/kvm_host.h
arch/arm/include/uapi/asm/kvm.h
arch/arm/kvm/guest.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/pm-asm-offsets.c
arch/arm/mach-omap2/sleep33xx.S
arch/arm/mach-omap2/sleep43xx.S
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm64/Makefile
arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
arch/arm64/boot/dts/arm/juno-motherboard.dtsi
arch/arm64/boot/dts/broadcom/stingray/stingray-sata.dtsi
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/asm/module.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/module-plts.c
arch/arm64/kernel/module.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/traps.c
arch/arm64/kvm/guest.c
arch/arm64/kvm/sys_regs.c
arch/arm64/lib/Makefile
arch/arm64/mm/flush.c
arch/powerpc/include/asm/powernv.h
arch/powerpc/kernel/mce_power.c
arch/powerpc/kernel/smp.c
arch/powerpc/kvm/booke.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/powernv/memtrace.c
arch/powerpc/platforms/powernv/npu-dma.c
arch/powerpc/platforms/powernv/opal-rtc.c
arch/sparc/include/uapi/asm/oradax.h
arch/sparc/kernel/vio.c
arch/x86/Kconfig
arch/x86/entry/entry_64_compat.S
arch/x86/events/intel/core.c
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/irq_vectors.h
arch/x86/include/asm/jailhouse_para.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/pgtable_64_types.h
arch/x86/include/uapi/asm/msgbuf.h
arch/x86/include/uapi/asm/shmbuf.h
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/microcode/intel.c
arch/x86/kernel/jailhouse.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.h
arch/x86/mm/pageattr.c
arch/x86/mm/pti.c
crypto/api.c
crypto/drbg.c
drivers/amba/bus.c
drivers/android/binder.c
drivers/base/firmware_loader/fallback.c
drivers/base/firmware_loader/fallback.h
drivers/bus/Kconfig
drivers/cpufreq/powernv-cpufreq.c
drivers/firmware/arm_scmi/clock.c
drivers/fpga/altera-ps-spi.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdkfd/Kconfig
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
drivers/gpu/drm/msm/disp/mdp_format.c
drivers/gpu/drm/msm/disp/mdp_kms.h
drivers/gpu/drm/msm/dsi/dsi_host.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c
drivers/gpu/drm/msm/msm_fb.c
drivers/gpu/drm/msm/msm_fbdev.c
drivers/gpu/drm/msm/msm_gem.c
drivers/gpu/drm/msm/msm_kms.h
drivers/gpu/drm/qxl/qxl_cmd.c
drivers/gpu/drm/qxl/qxl_drv.h
drivers/gpu/drm/qxl/qxl_ioctl.c
drivers/gpu/drm/qxl/qxl_release.c
drivers/gpu/drm/sun4i/sun4i_lvds.c
drivers/gpu/drm/virtio/virtgpu_vq.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-sprd.c
drivers/i2c/i2c-dev.c
drivers/input/evdev.c
drivers/memory/emif-asm-offsets.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/nand/core.c
drivers/mtd/nand/raw/marvell_nand.c
drivers/mtd/nand/raw/tango_nand.c
drivers/mtd/spi-nor/cadence-quadspi.c
drivers/of/fdt.c
drivers/rtc/rtc-opal.c
drivers/sbus/char/oradax.c
drivers/slimbus/messaging.c
drivers/soc/bcm/raspberrypi-power.c
drivers/staging/wilc1000/host_interface.c
drivers/tty/n_gsm.c
drivers/tty/serial/earlycon.c
drivers/tty/serial/imx.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/serial/qcom_geni_serial.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/tty_io.c
drivers/tty/tty_ldisc.c
drivers/uio/uio_hv_generic.c
drivers/usb/Kconfig
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/phy.c
drivers/usb/core/phy.h
drivers/usb/core/quirks.c
drivers/usb/host/xhci-dbgtty.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/musb_host.c
drivers/usb/serial/Kconfig
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/usb-serial-simple.c
drivers/usb/typec/ucsi/Makefile
drivers/usb/typec/ucsi/ucsi.c
drivers/usb/usbip/stub_main.c
drivers/usb/usbip/usbip_common.h
drivers/usb/usbip/usbip_event.c
drivers/usb/usbip/vhci_hcd.c
drivers/virt/vboxguest/vboxguest_core.c
drivers/virt/vboxguest/vboxguest_core.h
drivers/virt/vboxguest/vboxguest_linux.c
drivers/virt/vboxguest/vboxguest_utils.c
fs/ceph/xattr.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/cifs/smb2pdu.h
fs/cifs/smbdirect.c
fs/cifs/transport.c
fs/ext4/balloc.c
fs/ext4/extents.c
fs/ext4/super.c
fs/jbd2/transaction.c
include/asm-generic/vmlinux.lds.h
include/kvm/arm_psci.h
include/linux/device.h
include/linux/hrtimer.h
include/linux/mtd/flashchip.h
include/linux/serial_core.h
include/linux/stringhash.h
include/linux/ti-emif-sram.h
include/linux/timekeeper_internal.h
include/linux/timekeeping.h
include/linux/tty.h
include/linux/vbox_utils.h
include/soc/bcm2835/raspberrypi-firmware.h
include/sound/control.h
include/uapi/linux/kvm.h
include/uapi/linux/sysctl.h
include/uapi/linux/time.h
kernel/module.c
kernel/sysctl_binary.c
kernel/time/hrtimer.c
kernel/time/posix-stubs.c
kernel/time/posix-timers.c
kernel/time/tick-common.c
kernel/time/tick-internal.h
kernel/time/tick-sched.c
kernel/time/timekeeping.c
kernel/time/timekeeping.h
kernel/trace/trace.c
lib/kobject.c
mm/mmap.c
net/ceph/messenger.c
net/ceph/mon_client.c
sound/core/control.c
sound/core/pcm_compat.c
sound/core/pcm_native.c
sound/core/seq/oss/seq_oss_event.c
sound/core/seq/oss/seq_oss_midi.c
sound/core/seq/oss/seq_oss_synth.c
sound/core/seq/oss/seq_oss_synth.h
sound/drivers/opl3/opl3_synth.c
sound/firewire/dice/dice-stream.c
sound/firewire/dice/dice.c
sound/pci/asihpi/hpimsginit.c
sound/pci/asihpi/hpioctl.c
sound/pci/hda/hda_hwdep.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/rme9652/hdspm.c
sound/pci/rme9652/rme9652.c
sound/soc/amd/acp-da7219-max98357a.c
sound/soc/codecs/adau17x1.c
sound/soc/codecs/adau17x1.h
sound/soc/codecs/msm8916-wcd-analog.c
sound/soc/codecs/rt5514.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_ssi.c
sound/soc/intel/Kconfig
sound/soc/omap/omap-dmic.c
sound/soc/sh/rcar/core.c
sound/soc/soc-topology.c
sound/usb/mixer.c
sound/usb/mixer_maps.c
sound/usb/stream.c
sound/usb/usx2y/us122l.c
sound/usb/usx2y/usX2Yhwdep.c
sound/usb/usx2y/usx2yhwdeppcm.c
tools/perf/Documentation/perf-mem.txt
tools/perf/arch/s390/util/auxtrace.c
tools/perf/arch/s390/util/header.c
tools/perf/builtin-stat.c
tools/perf/pmu-events/arch/s390/mapfile.csv
tools/perf/tests/attr/test-record-group-sampling
tools/perf/tests/shell/record+probe_libc_inet_pton.sh
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/machine.c
tools/perf/util/parse-events.y
tools/perf/util/pmu.c
tools/testing/selftests/firmware/Makefile
tools/testing/selftests/firmware/fw_lib.sh
tools/testing/selftests/firmware/fw_run_tests.sh
tools/testing/selftests/x86/test_syscall_vdso.c
virt/kvm/arm/arm.c
virt/kvm/arm/psci.c
virt/kvm/arm/vgic/vgic-mmio-v2.c
virt/kvm/arm/vgic/vgic.c

index 8ff65fa632fdedd739b005027e198051f62c8c34..c06c045126fc9070ca8f4faefc18b17a8de85ee6 100644 (file)
@@ -21,7 +21,7 @@ Required properties:
 - interrupts : identifier to the device interrupt
 - clocks : a list of phandle + clock-specifier pairs, one for each
           entry in clock names.
-- clocks-names :
+- clock-names :
    * "xtal" for external xtal clock identifier
    * "pclk" for the bus core clock, either the clk81 clock or the gate clock
    * "baud" for the source of the baudrate generator, can be either the xtal
index 2ae2fee7e023c01375f7fa09b9b21f7f812293c1..b7e0e32b9ac62c1029ba93998b8257ce71478de4 100644 (file)
@@ -24,7 +24,7 @@ Required properties:
     - Must contain two elements for the extended variant of the IP
       (marvell,armada-3700-uart-ext): "uart-tx" and "uart-rx",
       respectively the UART TX interrupt and the UART RX interrupt. A
-      corresponding interrupts-names property must be defined.
+      corresponding interrupt-names property must be defined.
     - For backward compatibility reasons, a single element interrupts
       property is also supported for the standard variant of the IP,
       containing only the UART sum interrupt. This form is deprecated
index ad962f4ec3aaffe73991118aabd78b9da3d5cb87..a006ea4d065f7cdd0781ef2ef1ab1ee35827c5da 100644 (file)
@@ -17,6 +17,8 @@ Required properties:
     - "renesas,scifa-r8a7745" for R8A7745 (RZ/G1E) SCIFA compatible UART.
     - "renesas,scifb-r8a7745" for R8A7745 (RZ/G1E) SCIFB compatible UART.
     - "renesas,hscif-r8a7745" for R8A7745 (RZ/G1E) HSCIF compatible UART.
+    - "renesas,scif-r8a77470" for R8A77470 (RZ/G1C) SCIF compatible UART.
+    - "renesas,hscif-r8a77470" for R8A77470 (RZ/G1C) HSCIF compatible UART.
     - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART.
     - "renesas,scif-r8a7779" for R8A7779 (R-Car H1) SCIF compatible UART.
     - "renesas,scif-r8a7790" for R8A7790 (R-Car H2) SCIF compatible UART.
index c4c00dff4b569f94821a184784895a7aed1d315b..bd1dd316fb231f84d02a6125d566e881600df387 100644 (file)
@@ -28,7 +28,10 @@ Required properties:
   - interrupts: one XHCI interrupt should be described here.
 
 Optional properties:
-  - clocks: reference to a clock
+  - clocks: reference to the clocks
+  - clock-names: mandatory if there is a second clock, in this case
+    the name must be "core" for the first clock and "reg" for the
+    second one
   - usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
   - usb3-lpm-capable: determines if platform is USB3 LPM capable
   - quirk-broken-port-ped: set if the controller has broken port disable mechanism
index cf4516dfbf964b0ada60136fc49579df6c113823..d5ec95a7195bf001f6fa855dc6d7fa922ba40ed7 100644 (file)
@@ -17,17 +17,17 @@ an error is returned.
 
 request_firmware
 ----------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware
 
 request_firmware_direct
 -----------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_direct
 
 request_firmware_into_buf
 -------------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_into_buf
 
 Asynchronous firmware requests
@@ -41,7 +41,7 @@ in atomic contexts.
 
 request_firmware_nowait
 -----------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: request_firmware_nowait
 
 Special optimizations on reboot
@@ -50,12 +50,12 @@ Special optimizations on reboot
 Some devices have an optimization in place to enable the firmware to be
 retained during system reboot. When such optimizations are used the driver
 author must ensure the firmware is still available on resume from suspend,
-this can be done with firmware_request_cache() insted of requesting for the
-firmare to be loaded.
+this can be done with firmware_request_cache() instead of requesting for the
+firmware to be loaded.
 
 firmware_request_cache()
------------------------
-.. kernel-doc:: drivers/base/firmware_class.c
+------------------------
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :functions: firmware_request_cache
 
 request firmware API expected driver use
index 6d9ff316b608db48b46de6413d9503e23b51536a..bee1b9a1702f1cc6c89811aff6b8bdbc1eefb0b0 100644 (file)
@@ -28,7 +28,7 @@ Device Drivers Base
 .. kernel-doc:: drivers/base/node.c
    :internal:
 
-.. kernel-doc:: drivers/base/firmware_class.c
+.. kernel-doc:: drivers/base/firmware_loader/main.c
    :export:
 
 .. kernel-doc:: drivers/base/transport_class.c
index feb31946490b01c13106e2f9f43d1d28fd918ea0..48ff58095f115ae5c1d0c25e6987d187937dd365 100644 (file)
@@ -210,7 +210,7 @@ If the connector is dual-role capable, there may also be a switch for the data
 role. USB Type-C Connector Class does not supply separate API for them. The
 port drivers can use USB Role Class API with those.
 
-Illustration of the muxes behind a connector that supports an alternate mode:
+Illustration of the muxes behind a connector that supports an alternate mode::
 
                      ------------------------
                      |       Connector      |
index d04e6e4964ee7f88387f2e0e9ce3803b96d4ae18..fbed645ccd7563e90e86796d13cae7cfa7329748 100644 (file)
@@ -9,8 +9,8 @@ i2c adapters present on your system at a given time. i2cdetect is part of
 the i2c-tools package.
 
 I2C device files are character device files with major device number 89
-and a minor device number corresponding to the number assigned as 
-explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., 
+and a minor device number corresponding to the number assigned as
+explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
 i2c-10, ...). All 256 minor device numbers are reserved for i2c.
 
 
@@ -23,11 +23,6 @@ First, you need to include these two headers:
   #include <linux/i2c-dev.h>
   #include <i2c/smbus.h>
 
-(Please note that there are two files named "i2c-dev.h" out there. One is
-distributed with the Linux kernel and the other one is included in the
-source tree of i2c-tools. They used to be different in content but since 2012
-they're identical. You should use "linux/i2c-dev.h").
-
 Now, you have to decide which adapter you want to access. You should
 inspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
 Adapter numbers are assigned somewhat dynamically, so you can not
@@ -38,7 +33,7 @@ Next thing, open the device file, as follows:
   int file;
   int adapter_nr = 2; /* probably dynamically determined */
   char filename[20];
-  
+
   snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
   file = open(filename, O_RDWR);
   if (file < 0) {
@@ -72,8 +67,10 @@ the device supports them. Both are illustrated below.
     /* res contains the read word */
   }
 
-  /* Using I2C Write, equivalent of 
-     i2c_smbus_write_word_data(file, reg, 0x6543) */
+  /*
+   * Using I2C Write, equivalent of
+   * i2c_smbus_write_word_data(file, reg, 0x6543)
+   */
   buf[0] = reg;
   buf[1] = 0x43;
   buf[2] = 0x65;
@@ -140,14 +137,14 @@ ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)
   set in each message, overriding the values set with the above ioctl's.
 
 ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)
-  Not meant to be called  directly; instead, use the access functions
-  below.
+  If possible, use the provided i2c_smbus_* methods described below instead
+  of issuing direct ioctls.
 
 You can do plain i2c transactions by using read(2) and write(2) calls.
 You do not need to pass the address byte; instead, set it through
 ioctl I2C_SLAVE before you try to access the device.
 
-You can do SMBus level transactions (see documentation file smbus-protocol 
+You can do SMBus level transactions (see documentation file smbus-protocol
 for details) through the following functions:
   __s32 i2c_smbus_write_quick(int file, __u8 value);
   __s32 i2c_smbus_read_byte(int file);
@@ -158,7 +155,7 @@ for details) through the following functions:
   __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
   __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
-  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
+  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
                                    __u8 *values);
 All these transactions return -1 on failure; you can read errno to see
 what happened. The 'write' transactions return 0 on success; the
@@ -166,10 +163,9 @@ what happened. The 'write' transactions return 0 on success; the
 returns the number of values read. The block buffers need not be longer
 than 32 bytes.
 
-The above functions are all inline functions, that resolve to calls to
-the i2c_smbus_access function, that on its turn calls a specific ioctl
-with the data in a specific format. Read the source code if you
-want to know what happens behind the screens.
+The above functions are made available by linking against the libi2c library,
+which is provided by the i2c-tools project.  See:
+https://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
 
 
 Implementation details
index 84bb74dcae12e95acc4a2aa888462520422f693d..7f7413e597f3886ad046b9ca527b7d5fe19ecf56 100644 (file)
@@ -217,7 +217,6 @@ Code  Seq#(hex)     Include File            Comments
 'd'    02-40   pcmcia/ds.h             conflict!
 'd'    F0-FF   linux/digi1.h
 'e'    all     linux/digi1.h           conflict!
-'e'    00-1F   drivers/net/irda/irtty-sir.h    conflict!
 'f'    00-1F   linux/ext2_fs.h         conflict!
 'f'    00-1F   linux/ext3_fs.h         conflict!
 'f'    00-0F   fs/jfs/jfs_dinode.h     conflict!
@@ -247,7 +246,6 @@ Code  Seq#(hex)     Include File            Comments
 'm'    all     linux/synclink.h        conflict!
 'm'    00-19   drivers/message/fusion/mptctl.h conflict!
 'm'    00      drivers/scsi/megaraid/megaraid_ioctl.h  conflict!
-'m'    00-1F   net/irda/irmod.h        conflict!
 'n'    00-7F   linux/ncp_fs.h and fs/ncpfs/ioctl.c
 'n'    80-8F   uapi/linux/nilfs2_api.h NILFS2
 'n'    E0-FF   linux/matroxfb.h        matroxfb
index b583a73cf95f3b0bacbec3ca8cf3efd8c8c4c948..35ffaa281b269f9856c93c20344968e511ac175a 100644 (file)
@@ -2126,18 +2126,3 @@ max_dgram_qlen - INTEGER
 
        Default: 10
 
-
-UNDOCUMENTED:
-
-/proc/sys/net/irda/*
-       fast_poll_increase FIXME
-       warn_noreply_time FIXME
-       discovery_slots FIXME
-       slot_timeout FIXME
-       max_baud_rate FIXME
-       discovery_timeout FIXME
-       lap_keepalive_time FIXME
-       max_noreply_time FIXME
-       max_tx_data_size FIXME
-       max_tx_window FIXME
-       min_tx_turn_time FIXME
index 31abd04b957284f55697be1aa226e906c981196c..6f55eb960a6dc642159cb8b027c000c764d554a5 100644 (file)
@@ -168,7 +168,7 @@ update on the CPUs, as discussed below:
 
 [Please bear in mind that the kernel requests the microcode images from
 userspace, using the request_firmware() function defined in
-drivers/base/firmware_class.c]
+drivers/base/firmware_loader/main.c]
 
 
 a. When all the CPUs are identical:
index 00cecf1fcba9f34808cf27053afc0543d852ef2a..633be1043690dde2bbd45a09387843cdb5e13b84 100644 (file)
@@ -157,8 +157,5 @@ memory management. See ``include/sound/sndmagic.h`` for complete list of them. M
 OSS sound drivers have their magic numbers constructed from the soundcard PCI
 ID - these are not listed here as well.
 
-IrDA subsystem also uses large number of own magic numbers, see
-``include/net/irda/irda.h`` for a complete list of them.
-
 HFS is another larger user of magic numbers - you can find them in
 ``fs/hfs/hfs.h``.
index e45f0786f3f9ef29bb1da2f9c2b3c8d7430adc85..67d9c38e95eb54d2855bf356b6fccc0cace8442a 100644 (file)
@@ -461,9 +461,17 @@ of ftrace. Here is a list of some of the key files:
                and ticks at the same rate as the hardware clocksource.
 
        boot:
-               Same as mono. Used to be a separate clock which accounted
-               for the time spent in suspend while CLOCK_MONOTONIC did
-               not.
+               This is the boot clock (CLOCK_BOOTTIME) and is based on the
+               fast monotonic clock, but also accounts for time spent in
+               suspend. Since the clock access is designed for use in
+               tracing in the suspend path, some side effects are possible
+               if clock is accessed after the suspend time is accounted before
+               the fast mono clock is updated. In this case, the clock update
+               appears to happen slightly sooner than it normally would have.
+               Also on 32-bit systems, it's possible that the 64-bit boot offset
+               sees a partial update. These effects are rare and post
+               processing should be able to handle them. See comments in the
+               ktime_get_boot_fast_ns() function for more information.
 
        To set a clock, simply echo the clock name into this file::
 
index 1c7958b57fe9fd52d337862fa9b6b5d46ca2e9f8..758bf403a169dac0db8ec259bc611986aea69cfd 100644 (file)
@@ -1960,6 +1960,9 @@ ARM 32-bit VFP control registers have the following id bit patterns:
 ARM 64-bit FP registers have the following id bit patterns:
   0x4030 0000 0012 0 <regno:12>
 
+ARM firmware pseudo-registers have the following bit pattern:
+  0x4030 0000 0014 <regno:16>
+
 
 arm64 registers are mapped using the lower 32 bits. The upper 16 of
 that is the register group type, or coprocessor number:
@@ -1976,6 +1979,9 @@ arm64 CCSIDR registers are demultiplexed by CSSELR value:
 arm64 system registers have the following id bit patterns:
   0x6030 0000 0013 <op0:2> <op1:3> <crn:4> <crm:4> <op2:3>
 
+arm64 firmware pseudo-registers have the following bit pattern:
+  0x6030 0000 0014 <regno:16>
+
 
 MIPS registers are mapped using the lower 32 bits.  The upper 16 of that is
 the register group type:
@@ -2510,7 +2516,8 @@ Possible features:
          and execute guest code when KVM_RUN is called.
        - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode.
          Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only).
-       - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 for the CPU.
+       - KVM_ARM_VCPU_PSCI_0_2: Emulate PSCI v0.2 (or a future revision
+          backward compatible with v0.2) for the CPU.
          Depends on KVM_CAP_ARM_PSCI_0_2.
        - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU.
          Depends on KVM_CAP_ARM_PMU_V3.
diff --git a/Documentation/virtual/kvm/arm/psci.txt b/Documentation/virtual/kvm/arm/psci.txt
new file mode 100644 (file)
index 0000000..aafdab8
--- /dev/null
@@ -0,0 +1,30 @@
+KVM implements the PSCI (Power State Coordination Interface)
+specification in order to provide services such as CPU on/off, reset
+and power-off to the guest.
+
+The PSCI specification is regularly updated to provide new features,
+and KVM implements these updates if they make sense from a virtualization
+point of view.
+
+This means that a guest booted on two different versions of KVM can
+observe two different "firmware" revisions. This could cause issues if
+a given guest is tied to a particular PSCI revision (unlikely), or if
+a migration causes a different PSCI version to be exposed out of the
+blue to an unsuspecting guest.
+
+In order to remedy this situation, KVM exposes a set of "firmware
+pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
+interface. These registers can be saved/restored by userspace, and set
+to a convenient value if required.
+
+The following register is defined:
+
+* KVM_REG_ARM_PSCI_VERSION:
+
+  - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
+    (and thus has already been initialized)
+  - Returns the current PSCI version on GET_ONE_REG (defaulting to the
+    highest PSCI version implemented by KVM and compatible with v0.2)
+  - Allows any PSCI version implemented by KVM and compatible with
+    v0.2 to be set with SET_ONE_REG
+  - Affects the whole VM (even if the register view is per-vcpu)
index dd66ae9a847e1e54be1d1eb7543f2e3f0401b09b..79bb02ff812f52dc39c9519442142f395f73fc15 100644 (file)
@@ -564,8 +564,9 @@ S:  Maintained
 F:     drivers/media/dvb-frontends/af9033*
 
 AFFS FILE SYSTEM
+M:     David Sterba <dsterba@suse.com>
 L:     linux-fsdevel@vger.kernel.org
-S:     Orphan
+S:     Odd Fixes
 F:     Documentation/filesystems/affs.txt
 F:     fs/affs/
 
@@ -905,6 +906,8 @@ ANDROID ION DRIVER
 M:     Laura Abbott <labbott@redhat.com>
 M:     Sumit Semwal <sumit.semwal@linaro.org>
 L:     devel@driverdev.osuosl.org
+L:     dri-devel@lists.freedesktop.org
+L:     linaro-mm-sig@lists.linaro.org (moderated for non-subscribers)
 S:     Supported
 F:     drivers/staging/android/ion
 F:     drivers/staging/android/uapi/ion.h
@@ -1208,7 +1211,6 @@ F:        drivers/*/*alpine*
 ARM/ARTPEC MACHINE SUPPORT
 M:     Jesper Nilsson <jesper.nilsson@axis.com>
 M:     Lars Persson <lars.persson@axis.com>
-M:     Niklas Cassel <niklas.cassel@axis.com>
 S:     Maintained
 L:     linux-arm-kernel@axis.com
 F:     arch/arm/mach-artpec
@@ -7411,16 +7413,6 @@ S:       Obsolete
 F:     include/uapi/linux/ipx.h
 F:     drivers/staging/ipx/
 
-IRDA SUBSYSTEM
-M:     Samuel Ortiz <samuel@sortiz.org>
-L:     irda-users@lists.sourceforge.net (subscribers-only)
-L:     netdev@vger.kernel.org
-W:     http://irda.sourceforge.net/
-S:     Obsolete
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
-F:     Documentation/networking/irda.txt
-F:     drivers/staging/irda/
-
 IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
 M:     Marc Zyngier <marc.zyngier@arm.com>
 S:     Maintained
@@ -7753,7 +7745,7 @@ F:        arch/x86/include/asm/svm.h
 F:     arch/x86/kvm/svm.c
 
 KERNEL VIRTUAL MACHINE FOR ARM (KVM/arm)
-M:     Christoffer Dall <christoffer.dall@linaro.org>
+M:     Christoffer Dall <christoffer.dall@arm.com>
 M:     Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
@@ -7767,7 +7759,7 @@ F:        virt/kvm/arm/
 F:     include/kvm/arm_*
 
 KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64)
-M:     Christoffer Dall <christoffer.dall@linaro.org>
+M:     Christoffer Dall <christoffer.dall@arm.com>
 M:     Marc Zyngier <marc.zyngier@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     kvmarm@lists.cs.columbia.edu
@@ -10909,7 +10901,6 @@ F:      drivers/pci/host/
 F:     drivers/pci/dwc/
 
 PCIE DRIVER FOR AXIS ARTPEC
-M:     Niklas Cassel <niklas.cassel@axis.com>
 M:     Jesper Nilsson <jesper.nilsson@axis.com>
 L:     linux-arm-kernel@axis.com
 L:     linux-pci@vger.kernel.org
@@ -13965,7 +13956,7 @@ THUNDERBOLT DRIVER
 M:     Andreas Noever <andreas.noever@gmail.com>
 M:     Michael Jamet <michael.jamet@intel.com>
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
-M:     Yehezkel Bernat <yehezkel.bernat@intel.com>
+M:     Yehezkel Bernat <YehezkelShB@gmail.com>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
 S:     Maintained
 F:     Documentation/admin-guide/thunderbolt.rst
@@ -13975,7 +13966,7 @@ F:      include/linux/thunderbolt.h
 THUNDERBOLT NETWORK DRIVER
 M:     Michael Jamet <michael.jamet@intel.com>
 M:     Mika Westerberg <mika.westerberg@linux.intel.com>
-M:     Yehezkel Bernat <yehezkel.bernat@intel.com>
+M:     Yehezkel Bernat <YehezkelShB@gmail.com>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/thunderbolt.c
index 83b6c541565ac4a2c6c4fe777a4ebce0b8653a30..619a85ad716b43e2aafa080eb5e85da9516d5459 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 4
 PATCHLEVEL = 17
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
index 8bbb6f85d1618b3743bed54612ffe769141c850b..4785fbcc41ed840f0e72507163d2374532925395 100644 (file)
@@ -134,37 +134,37 @@ mux {
                                                function = "gmii";
                                                groups = "gmii_gmac0_grp";
                                        };
-                                       /* Settings come from OpenWRT */
+                                       /* Settings come from OpenWRT, pins on SL3516 */
                                        conf0 {
-                                               pins = "R8 GMAC0 RXDV", "U11 GMAC1 RXDV";
+                                               pins = "V8 GMAC0 RXDV", "T10 GMAC1 RXDV";
                                                skew-delay = <0>;
                                        };
                                        conf1 {
-                                               pins = "T8 GMAC0 RXC", "T11 GMAC1 RXC";
+                                               pins = "Y7 GMAC0 RXC", "Y11 GMAC1 RXC";
                                                skew-delay = <15>;
                                        };
                                        conf2 {
-                                               pins = "P8 GMAC0 TXEN", "V11 GMAC1 TXEN";
+                                               pins = "T8 GMAC0 TXEN", "W11 GMAC1 TXEN";
                                                skew-delay = <7>;
                                        };
                                        conf3 {
-                                               pins = "V7 GMAC0 TXC";
+                                               pins = "U8 GMAC0 TXC";
                                                skew-delay = <11>;
                                        };
                                        conf4 {
-                                               pins = "P10 GMAC1 TXC";
+                                               pins = "V11 GMAC1 TXC";
                                                skew-delay = <10>;
                                        };
                                        conf5 {
                                                /* The data lines all have default skew */
-                                               pins = "U8 GMAC0 RXD0", "V8 GMAC0 RXD1",
-                                                      "P9 GMAC0 RXD2", "R9 GMAC0 RXD3",
-                                                      "U7 GMAC0 TXD0", "T7 GMAC0 TXD1",
-                                                      "R7 GMAC0 TXD2", "P7 GMAC0 TXD3",
-                                                      "R11 GMAC1 RXD0", "P11 GMAC1 RXD1",
-                                                      "V12 GMAC1 RXD2", "U12 GMAC1 RXD3",
-                                                      "R10 GMAC1 TXD0", "T10 GMAC1 TXD1",
-                                                      "U10 GMAC1 TXD2", "V10 GMAC1 TXD3";
+                                               pins = "W8 GMAC0 RXD0", "V9 GMAC0 RXD1",
+                                                      "Y8 GMAC0 RXD2", "U9 GMAC0 RXD3",
+                                                      "T7 GMAC0 TXD0", "U6 GMAC0 TXD1",
+                                                      "V7 GMAC0 TXD2", "U7 GMAC0 TXD3",
+                                                      "Y12 GMAC1 RXD0", "V12 GMAC1 RXD1",
+                                                      "T11 GMAC1 RXD2", "W12 GMAC1 RXD3",
+                                                      "U10 GMAC1 TXD0", "Y10 GMAC1 TXD1",
+                                                      "W10 GMAC1 TXD2", "T9 GMAC1 TXD3";
                                                skew-delay = <7>;
                                        };
                                        /* Set up drive strength on GMAC0 to 16 mA */
index 475904894b8633464173b1b76f85e378c13ff4cb..e554b6e039f32fe396386bd6f7c32e9b4869ecf8 100644 (file)
@@ -163,10 +163,10 @@ cm1_clockdomains: clockdomains {
 
                        cm2: cm2@8000 {
                                compatible = "ti,omap4-cm2", "simple-bus";
-                               reg = <0x8000 0x3000>;
+                               reg = <0x8000 0x2000>;
                                #address-cells = <1>;
                                #size-cells = <1>;
-                               ranges = <0 0x8000 0x3000>;
+                               ranges = <0 0x8000 0x2000>;
 
                                cm2_clocks: clocks {
                                        #address-cells = <1>;
@@ -250,11 +250,11 @@ counter32k: counter@4000 {
 
                                prm: prm@6000 {
                                        compatible = "ti,omap4-prm";
-                                       reg = <0x6000 0x3000>;
+                                       reg = <0x6000 0x2000>;
                                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                        #address-cells = <1>;
                                        #size-cells = <1>;
-                                       ranges = <0 0x6000 0x3000>;
+                                       ranges = <0 0x6000 0x2000>;
 
                                        prm_clocks: clocks {
                                                #address-cells = <1>;
index 2a63fa10c813042bf2b98261964c7b6cd9f03790..553777ac28146f053983a1903ddf568a5bdd3c31 100644 (file)
@@ -1,6 +1,7 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_USER_NS=y
 CONFIG_RELAY=y
@@ -12,15 +13,21 @@ CONFIG_ARCH_GEMINI=y
 CONFIG_PCI=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
 CONFIG_KEXEC=y
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_CFI_STAA=y
@@ -33,6 +40,11 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_ATA=y
 CONFIG_PATA_FTIDE010=y
+CONFIG_NETDEVICES=y
+CONFIG_GEMINI_ETHERNET=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_REALTEK_PHY=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
@@ -43,9 +55,19 @@ CONFIG_SERIAL_8250_NR_UARTS=1
 CONFIG_SERIAL_8250_RUNTIME_UARTS=1
 CONFIG_SERIAL_OF_PLATFORM=y
 # CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SENSORS_GPIO_FAN=y
+CONFIG_SENSORS_LM75=y
+CONFIG_THERMAL=y
 CONFIG_WATCHDOG=y
-CONFIG_GEMINI_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_DRM=y
+CONFIG_DRM_PANEL_ILITEK_IL9322=y
+CONFIG_DRM_TVE200=y
+CONFIG_LOGO=y
 CONFIG_USB=y
 CONFIG_USB_MON=y
 CONFIG_USB_FOTG210_HCD=y
@@ -54,6 +76,7 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
 CONFIG_DMADEVICES=y
index 2620ce790db0afaa18ed4d51eca2d886a21b00a8..371fca4e1ab7deafe2d8aed06ac5fd4092c7a8e4 100644 (file)
@@ -57,6 +57,7 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_SPI_NOR=y
+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_OF_OVERLAY=y
 CONFIG_OF_CONFIGFS=y
index c6a749568dd6c413603ef3b7554561f356b33cc9..c7c28c885a1946de9a012311cbca7861d93a67da 100644 (file)
@@ -77,6 +77,9 @@ struct kvm_arch {
        /* Interrupt controller */
        struct vgic_dist        vgic;
        int max_vcpus;
+
+       /* Mandated version of PSCI */
+       u32 psci_version;
 };
 
 #define KVM_NR_MEM_OBJS     40
index 2ba95d6fe852d7bed7460b022f1ed5b8409caacd..caae4843cb7001fbee1fa9b222850df7006850fb 100644 (file)
@@ -195,6 +195,12 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_VFP_FPINST         0x1009
 #define KVM_REG_ARM_VFP_FPINST2                0x100A
 
+/* KVM-as-firmware specific pseudo-registers */
+#define KVM_REG_ARM_FW                 (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_FW_REG(r)          (KVM_REG_ARM | KVM_REG_SIZE_U64 | \
+                                        KVM_REG_ARM_FW | ((r) & 0xffff))
+#define KVM_REG_ARM_PSCI_VERSION       KVM_REG_ARM_FW_REG(0)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR      0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
index 1e0784ebbfd6db77595652961ad3c48c41fceabe..a18f33edc471a92fcf6194dbe6601bc4b94f1988 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <kvm/arm_psci.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/kvm.h>
@@ -176,6 +177,7 @@ static unsigned long num_core_regs(void)
 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 {
        return num_core_regs() + kvm_arm_num_coproc_regs(vcpu)
+               + kvm_arm_get_fw_num_regs(vcpu)
                + NUM_TIMER_REGS;
 }
 
@@ -196,6 +198,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
                uindices++;
        }
 
+       ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices);
+       if (ret)
+               return ret;
+       uindices += kvm_arm_get_fw_num_regs(vcpu);
+
        ret = copy_timer_indices(vcpu, uindices);
        if (ret)
                return ret;
@@ -214,6 +221,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return get_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_get_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return get_timer_reg(vcpu, reg);
 
@@ -230,6 +240,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return set_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_set_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return set_timer_reg(vcpu, reg);
 
index 4603c30fef73a721b8564ed74ffe63ce21b5966c..0d9ce58bc464a87249f1551a0882c18d5009bc5d 100644 (file)
@@ -243,8 +243,4 @@ arch/arm/mach-omap2/pm-asm-offsets.s: arch/arm/mach-omap2/pm-asm-offsets.c
 include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE
        $(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__)
 
-# For rule to generate ti-emif-asm-offsets.h dependency
-include drivers/memory/Makefile.asm-offsets
-
-arch/arm/mach-omap2/sleep33xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
-arch/arm/mach-omap2/sleep43xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h
+$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h
index 6d4392da7c11008dcc2f2c6eb762e1c850b22190..b9846b19e5e2c7b9737085e23c56d83e0d0a6f67 100644 (file)
@@ -7,9 +7,12 @@
 
 #include <linux/kbuild.h>
 #include <linux/platform_data/pm33xx.h>
+#include <linux/ti-emif-sram.h>
 
 int main(void)
 {
+       ti_emif_asm_offsets();
+
        DEFINE(AMX3_PM_WFI_FLAGS_OFFSET,
               offsetof(struct am33xx_pm_sram_data, wfi_flags));
        DEFINE(AMX3_PM_L2_AUX_CTRL_VAL_OFFSET,
index 218d79930b04623c24af79aa75468186a1b39f67..322b3bb868b49766f53ac807674ced65b5b42bc9 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-emif-asm-offsets.h>
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
index b24be624e8b993d12ad7768cb2ed1ecea4676734..8903814a6677d327579f9410f9b9b641e23ed97a 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-emif-asm-offsets.h>
 #include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
index 59589a4a0d4b2023b628e9485aec98849c0f4c76..885e8f12e4b911bfaaf74ce8a8f9767b95bd08e7 100644 (file)
@@ -427,9 +427,9 @@ static struct gpiod_lookup_table jive_wm8750_gpiod_table = {
        .dev_id         = "spi_gpio",
        .table          = {
                GPIO_LOOKUP("GPIOB", 4,
-                           "gpio-sck", GPIO_ACTIVE_HIGH),
+                           "sck", GPIO_ACTIVE_HIGH),
                GPIO_LOOKUP("GPIOB", 9,
-                           "gpio-mosi", GPIO_ACTIVE_HIGH),
+                           "mosi", GPIO_ACTIVE_HIGH),
                GPIO_LOOKUP("GPIOH", 10,
                            "cs", GPIO_ACTIVE_HIGH),
                { },
index 15402861bb59eb9377682e56453965e7713592ca..87f7d2f9f17c266fee66973f29b6efd6c0590a71 100644 (file)
@@ -56,7 +56,11 @@ KBUILD_AFLAGS        += $(lseinstr) $(brokengasinst)
 KBUILD_CFLAGS  += $(call cc-option,-mabi=lp64)
 KBUILD_AFLAGS  += $(call cc-option,-mabi=lp64)
 
+ifeq ($(cc-name),clang)
+KBUILD_CFLAGS  += -DCONFIG_ARCH_SUPPORTS_INT128
+else
 KBUILD_CFLAGS  += $(call cc-ifversion, -ge, 0500, -DCONFIG_ARCH_SUPPORTS_INT128)
+endif
 
 ifeq ($(CONFIG_CPU_BIG_ENDIAN), y)
 KBUILD_CPPFLAGS        += -mbig-endian
index 4eef36b2253865833a659be0ca5b3f2ab1b34cb7..88e712ea757a238152c06f932dfecfeb5b36b843 100644 (file)
@@ -212,3 +212,7 @@ &uart_AO {
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index 22bf37404ff1b41ba74b96702d523a517e978c9c..3e3eb31748a35a7790a9dc90e56971f004660298 100644 (file)
@@ -271,3 +271,15 @@ &uart_AO {
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
+
+&usb2_phy0 {
+       /*
+        * even though the schematics don't show it:
+        * HDMI_5V is also used as supply for the USB VBUS.
+        */
+       phy-supply = <&hdmi_5v>;
+};
index 69c721a70e44b7c377040c2428833fc141f0ddf0..6739697be1defd72693e1e867c172a85cfe643ba 100644 (file)
@@ -215,3 +215,7 @@ &uart_AO {
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index 0a0953fbc7d42b776a6b4d64f8da6a041ae30cb3..0cfd701809dec578ac31f5f68a7fcfbc21822619 100644 (file)
@@ -185,3 +185,7 @@ &uart_AO {
        pinctrl-0 = <&uart_ao_a_pins>;
        pinctrl-names = "default";
 };
+
+&usb0 {
+       status = "okay";
+};
index e1a39cbed8c9c18abf90c521ba09dbd5356b7502..dba365ed4bd5f903e34f4c6fdf1b14d539db0d89 100644 (file)
@@ -20,6 +20,67 @@ secmon_reserved_alt: secmon@5000000 {
                        no-map;
                };
        };
+
+       soc {
+               usb0: usb@c9000000 {
+                       status = "disabled";
+                       compatible = "amlogic,meson-gxl-dwc3";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       clocks = <&clkc CLKID_USB>;
+                       clock-names = "usb_general";
+                       resets = <&reset RESET_USB_OTG>;
+                       reset-names = "usb_otg";
+
+                       dwc3: dwc3@c9000000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x0 0xc9000000 0x0 0x100000>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               dr_mode = "host";
+                               maximum-speed = "high-speed";
+                               snps,dis_u2_susphy_quirk;
+                               phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>;
+                       };
+               };
+       };
+};
+
+&apb {
+       usb2_phy0: phy@78000 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78000 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+
+       usb2_phy1: phy@78020 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78020 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+
+       usb3_phy: phy@78080 {
+               compatible = "amlogic,meson-gxl-usb3-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78080 0x0 0x20>;
+               interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&clkc CLKID_USB>, <&clkc_AO CLKID_AO_CEC_32K>;
+               clock-names = "phy", "peripheral";
+               resets = <&reset RESET_USB_OTG>, <&reset RESET_USB_OTG>;
+               reset-names = "phy", "peripheral";
+               status = "okay";
+       };
 };
 
 &ethmac {
index 4fd46c1546a7e5a82ec63dc50e15a2e0ae65d3e3..0868da476e41ff1a81aa40be378a13737c2a2c4a 100644 (file)
@@ -406,3 +406,7 @@ &saradc {
        status = "okay";
        vref-supply = <&vddio_ao18>;
 };
+
+&usb0 {
+       status = "okay";
+};
index d076a7c425dddd683ed81a9cfcb45fc7f2df682a..247888d68a3aabe06e8841a8d93cbfe8afe12960 100644 (file)
@@ -80,6 +80,19 @@ cpu7: cpu@103 {
        };
 };
 
+&apb {
+       usb2_phy2: phy@78040 {
+               compatible = "amlogic,meson-gxl-usb2-phy";
+               #phy-cells = <0>;
+               reg = <0x0 0x78040 0x0 0x20>;
+               clocks = <&clkc CLKID_USB>;
+               clock-names = "phy";
+               resets = <&reset RESET_USB_OTG>;
+               reset-names = "phy";
+               status = "okay";
+       };
+};
+
 &clkc_AO {
        compatible = "amlogic,meson-gxm-aoclkc", "amlogic,meson-gx-aoclkc";
 };
@@ -100,3 +113,7 @@ &vpu {
 &hdmi_tx {
        compatible = "amlogic,meson-gxm-dw-hdmi", "amlogic,meson-gx-dw-hdmi";
 };
+
+&dwc3 {
+       phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>;
+};
index 2ac43221ddb680acafd1507a866da58514a53370..69804c5f1197caac2815199edde847a547a0ae03 100644 (file)
@@ -56,8 +56,6 @@ mb_fixed_3v3: mcc-sb-3v3 {
 
                        gpio_keys {
                                compatible = "gpio-keys";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
 
                                power-button {
                                        debounce_interval = <50>;
index 4b5465da81d8e29ac616fc18de3f1351e81321ed..8c68e0c26f1b281c0259fd0f5cca18d2eebcb8a4 100644 (file)
@@ -36,11 +36,11 @@ sata {
                #size-cells = <1>;
                ranges = <0x0 0x0 0x67d00000 0x00800000>;
 
-               sata0: ahci@210000 {
+               sata0: ahci@0 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00210000 0x1000>;
+                       reg = <0x00000000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -52,9 +52,9 @@ sata0_port0: sata-port@0 {
                        };
                };
 
-               sata_phy0: sata_phy@212100 {
+               sata_phy0: sata_phy@2100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00212100 0x1000>;
+                       reg = <0x00002100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -66,11 +66,11 @@ sata0_phy0: sata-phy@0 {
                        };
                };
 
-               sata1: ahci@310000 {
+               sata1: ahci@10000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00310000 0x1000>;
+                       reg = <0x00010000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -82,9 +82,9 @@ sata1_port0: sata-port@0 {
                        };
                };
 
-               sata_phy1: sata_phy@312100 {
+               sata_phy1: sata_phy@12100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00312100 0x1000>;
+                       reg = <0x00012100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -96,11 +96,11 @@ sata1_phy0: sata-phy@0 {
                        };
                };
 
-               sata2: ahci@120000 {
+               sata2: ahci@20000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00120000 0x1000>;
+                       reg = <0x00020000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -112,9 +112,9 @@ sata2_port0: sata-port@0 {
                        };
                };
 
-               sata_phy2: sata_phy@122100 {
+               sata_phy2: sata_phy@22100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00122100 0x1000>;
+                       reg = <0x00022100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -126,11 +126,11 @@ sata2_phy0: sata-phy@0 {
                        };
                };
 
-               sata3: ahci@130000 {
+               sata3: ahci@30000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00130000 0x1000>;
+                       reg = <0x00030000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -142,9 +142,9 @@ sata3_port0: sata-port@0 {
                        };
                };
 
-               sata_phy3: sata_phy@132100 {
+               sata_phy3: sata_phy@32100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00132100 0x1000>;
+                       reg = <0x00032100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -156,11 +156,11 @@ sata3_phy0: sata-phy@0 {
                        };
                };
 
-               sata4: ahci@330000 {
+               sata4: ahci@100000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00330000 0x1000>;
+                       reg = <0x00100000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -172,9 +172,9 @@ sata4_port0: sata-port@0 {
                        };
                };
 
-               sata_phy4: sata_phy@332100 {
+               sata_phy4: sata_phy@102100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00332100 0x1000>;
+                       reg = <0x00102100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -186,11 +186,11 @@ sata4_phy0: sata-phy@0 {
                        };
                };
 
-               sata5: ahci@400000 {
+               sata5: ahci@110000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00400000 0x1000>;
+                       reg = <0x00110000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -202,9 +202,9 @@ sata5_port0: sata-port@0 {
                        };
                };
 
-               sata_phy5: sata_phy@402100 {
+               sata_phy5: sata_phy@112100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00402100 0x1000>;
+                       reg = <0x00112100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -216,11 +216,11 @@ sata5_phy0: sata-phy@0 {
                        };
                };
 
-               sata6: ahci@410000 {
+               sata6: ahci@120000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00410000 0x1000>;
+                       reg = <0x00120000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -232,9 +232,9 @@ sata6_port0: sata-port@0 {
                        };
                };
 
-               sata_phy6: sata_phy@412100 {
+               sata_phy6: sata_phy@122100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00412100 0x1000>;
+                       reg = <0x00122100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
@@ -246,11 +246,11 @@ sata6_phy0: sata-phy@0 {
                        };
                };
 
-               sata7: ahci@420000 {
+               sata7: ahci@130000 {
                        compatible = "brcm,iproc-ahci", "generic-ahci";
-                       reg = <0x00420000 0x1000>;
+                       reg = <0x00130000 0x1000>;
                        reg-names = "ahci";
-                       interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
@@ -262,9 +262,9 @@ sata7_port0: sata-port@0 {
                        };
                };
 
-               sata_phy7: sata_phy@422100 {
+               sata_phy7: sata_phy@132100 {
                        compatible = "brcm,iproc-sr-sata-phy";
-                       reg = <0x00422100 0x1000>;
+                       reg = <0x00132100 0x1000>;
                        reg-names = "phy";
                        #address-cells = <1>;
                        #size-cells = <0>;
index ab46bc70add636e0793f32083f800ff06bf80353..469de8acd06f5fa4103d9f55d0fb4c4c97d853a9 100644 (file)
@@ -75,6 +75,9 @@ struct kvm_arch {
 
        /* Interrupt controller */
        struct vgic_dist        vgic;
+
+       /* Mandated version of PSCI */
+       u32 psci_version;
 };
 
 #define KVM_NR_MEM_OBJS     40
index b6dbbe3123a9a9f8308a07b9257bfe968c184804..97d0ef12e2ff561938acdf96196a1a213664c522 100644 (file)
@@ -39,7 +39,7 @@ struct mod_arch_specific {
 u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
                          Elf64_Sym *sym);
 
-u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val);
+u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val);
 
 #ifdef CONFIG_RANDOMIZE_BASE
 extern u64 module_alloc_base;
index 7e2c27e63cd894371655a569046faaa67cfc1837..7c4c8f318ba999afdac0b41300c9613fe161e91d 100644 (file)
@@ -230,7 +230,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
        }
 }
 
-extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
+extern void __sync_icache_dcache(pte_t pteval);
 
 /*
  * PTE bits configuration in the presence of hardware Dirty Bit Management
@@ -253,7 +253,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
        pte_t old_pte;
 
        if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte))
-               __sync_icache_dcache(pte, addr);
+               __sync_icache_dcache(pte);
 
        /*
         * If the existing pte is valid, check for potential race with
index 9abbf30446545a0668083b0891461f015563bcb1..04b3256f8e6d5f8e3e368b043f0fdcfeb7c23164 100644 (file)
@@ -206,6 +206,12 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_TIMER_CNT          ARM64_SYS_REG(3, 3, 14, 3, 2)
 #define KVM_REG_ARM_TIMER_CVAL         ARM64_SYS_REG(3, 3, 14, 0, 2)
 
+/* KVM-as-firmware specific pseudo-registers */
+#define KVM_REG_ARM_FW                 (0x0014 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_FW_REG(r)          (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+                                        KVM_REG_ARM_FW | ((r) & 0xffff))
+#define KVM_REG_ARM_PSCI_VERSION       KVM_REG_ARM_FW_REG(0)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR      0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1
index 536d572e55967286b65457631251c842c1951353..9d1b06d67c53d4addacf97dd96207aa91d2ba04b 100644 (file)
@@ -868,6 +868,7 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
        static const struct midr_range kpti_safe_list[] = {
                MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
                MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
+               { /* sentinel */ }
        };
        char const *str = "command line option";
 
index fa3637284a3d8f4c7dbfe4b7e107af9af94f2685..f0690c2ca3e0f2f27f761a1568e6b3cc637779a4 100644 (file)
@@ -43,7 +43,7 @@ u64 module_emit_plt_entry(struct module *mod, void *loc, const Elf64_Rela *rela,
 }
 
 #ifdef CONFIG_ARM64_ERRATUM_843419
-u64 module_emit_adrp_veneer(struct module *mod, void *loc, u64 val)
+u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
 {
        struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
                                                          &mod->arch.init;
index 719fde8dcc19042b38164ddcaa7da429cd2180b2..155fd91e78f4a62180e7577355ca4a6b0eb283f4 100644 (file)
@@ -215,7 +215,7 @@ static int reloc_insn_adrp(struct module *mod, __le32 *place, u64 val)
                insn &= ~BIT(31);
        } else {
                /* out of range for ADR -> emit a veneer */
-               val = module_emit_adrp_veneer(mod, place, val & ~0xfff);
+               val = module_emit_veneer_for_adrp(mod, place, val & ~0xfff);
                if (!val)
                        return -ENOEXEC;
                insn = aarch64_insn_gen_branch_imm((u64)place, val,
index 71d99af24ef20852a18deea4d29a25c0197cf651..7ff81fed46e1ebeebfdd58eddc5c718af5f3d565 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sched/signal.h>
 #include <linux/sched/task_stack.h>
 #include <linux/mm.h>
+#include <linux/nospec.h>
 #include <linux/smp.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
@@ -249,15 +250,20 @@ static struct perf_event *ptrace_hbp_get_event(unsigned int note_type,
 
        switch (note_type) {
        case NT_ARM_HW_BREAK:
-               if (idx < ARM_MAX_BRP)
-                       bp = tsk->thread.debug.hbp_break[idx];
+               if (idx >= ARM_MAX_BRP)
+                       goto out;
+               idx = array_index_nospec(idx, ARM_MAX_BRP);
+               bp = tsk->thread.debug.hbp_break[idx];
                break;
        case NT_ARM_HW_WATCH:
-               if (idx < ARM_MAX_WRP)
-                       bp = tsk->thread.debug.hbp_watch[idx];
+               if (idx >= ARM_MAX_WRP)
+                       goto out;
+               idx = array_index_nospec(idx, ARM_MAX_WRP);
+               bp = tsk->thread.debug.hbp_watch[idx];
                break;
        }
 
+out:
        return bp;
 }
 
@@ -1458,9 +1464,7 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
 {
        int ret;
        u32 kdata;
-       mm_segment_t old_fs = get_fs();
 
-       set_fs(KERNEL_DS);
        /* Watchpoint */
        if (num < 0) {
                ret = compat_ptrace_hbp_get(NT_ARM_HW_WATCH, tsk, num, &kdata);
@@ -1471,7 +1475,6 @@ static int compat_ptrace_gethbpregs(struct task_struct *tsk, compat_long_t num,
        } else {
                ret = compat_ptrace_hbp_get(NT_ARM_HW_BREAK, tsk, num, &kdata);
        }
-       set_fs(old_fs);
 
        if (!ret)
                ret = put_user(kdata, data);
@@ -1484,7 +1487,6 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
 {
        int ret;
        u32 kdata = 0;
-       mm_segment_t old_fs = get_fs();
 
        if (num == 0)
                return 0;
@@ -1493,12 +1495,10 @@ static int compat_ptrace_sethbpregs(struct task_struct *tsk, compat_long_t num,
        if (ret)
                return ret;
 
-       set_fs(KERNEL_DS);
        if (num < 0)
                ret = compat_ptrace_hbp_set(NT_ARM_HW_WATCH, tsk, num, &kdata);
        else
                ret = compat_ptrace_hbp_set(NT_ARM_HW_BREAK, tsk, num, &kdata);
-       set_fs(old_fs);
 
        return ret;
 }
index 1cb2749a72bfed65cd33d3a24695ddef2bbce517..8bbdc17e49df79cab3e8576783216e91aef6c746 100644 (file)
@@ -277,7 +277,8 @@ void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size)
         * If we were single stepping, we want to get the step exception after
         * we return from the trap.
         */
-       user_fastforward_single_step(current);
+       if (user_mode(regs))
+               user_fastforward_single_step(current);
 }
 
 static LIST_HEAD(undef_hook);
index 959e50d2588c0f14b9eb9230522c3f12c3f7daf9..56a0260ceb11a95258099f0f19356b8989ff6afa 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
+#include <kvm/arm_psci.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/kvm.h>
@@ -205,7 +206,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
 {
        return num_core_regs() + kvm_arm_num_sys_reg_descs(vcpu)
-                + NUM_TIMER_REGS;
+               + kvm_arm_get_fw_num_regs(vcpu) + NUM_TIMER_REGS;
 }
 
 /**
@@ -225,6 +226,11 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
                uindices++;
        }
 
+       ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices);
+       if (ret)
+               return ret;
+       uindices += kvm_arm_get_fw_num_regs(vcpu);
+
        ret = copy_timer_indices(vcpu, uindices);
        if (ret)
                return ret;
@@ -243,6 +249,9 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return get_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_get_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return get_timer_reg(vcpu, reg);
 
@@ -259,6 +268,9 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
        if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE)
                return set_core_reg(vcpu, reg);
 
+       if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_FW)
+               return kvm_arm_set_fw_reg(vcpu, reg);
+
        if (is_timer_reg(reg->id))
                return set_timer_reg(vcpu, reg);
 
index 806b0b126a644dbc4e2f80db451370b63c63c6a5..6e3b969391fdbb853f621fa60f7c8760d79caa78 100644 (file)
@@ -996,14 +996,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
 
        if (id == SYS_ID_AA64PFR0_EL1) {
                if (val & (0xfUL << ID_AA64PFR0_SVE_SHIFT))
-                       pr_err_once("kvm [%i]: SVE unsupported for guests, suppressing\n",
-                                   task_pid_nr(current));
+                       kvm_debug("SVE unsupported for guests, suppressing\n");
 
                val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
        } else if (id == SYS_ID_AA64MMFR1_EL1) {
                if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
-                       pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n",
-                                   task_pid_nr(current));
+                       kvm_debug("LORegions unsupported for guests, suppressing\n");
 
                val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
        }
index 0ead8a1d167956193f5666dfa9a5365e0e94ebc8..137710f4dac30ac01c5c17856b730a996628a2e3 100644 (file)
@@ -19,5 +19,9 @@ CFLAGS_atomic_ll_sc.o := -fcall-used-x0 -ffixed-x1 -ffixed-x2         \
                   -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15   \
                   -fcall-saved-x18 -fomit-frame-pointer
 CFLAGS_REMOVE_atomic_ll_sc.o := -pg
+GCOV_PROFILE_atomic_ll_sc.o    := n
+KASAN_SANITIZE_atomic_ll_sc.o  := n
+KCOV_INSTRUMENT_atomic_ll_sc.o := n
+UBSAN_SANITIZE_atomic_ll_sc.o  := n
 
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
index e36ed5087b5cbba3f71c57937af82b1b00cb88e4..1059884f9a6f35231be04b2930c7ecf5c10b4105 100644 (file)
@@ -58,7 +58,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
        flush_ptrace_access(vma, page, uaddr, dst, len);
 }
 
-void __sync_icache_dcache(pte_t pte, unsigned long addr)
+void __sync_icache_dcache(pte_t pte)
 {
        struct page *page = pte_page(pte);
 
index d1c2d2e658cf4d5b1d3c3718a377efa345067128..2f3ff7a278815a131f9ebec73bffcdaedf0abab3 100644 (file)
@@ -15,7 +15,7 @@
 extern void powernv_set_nmmu_ptcr(unsigned long ptcr);
 extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                        unsigned long flags,
-                       struct npu_context *(*cb)(struct npu_context *, void *),
+                       void (*cb)(struct npu_context *, void *),
                        void *priv);
 extern void pnv_npu2_destroy_context(struct npu_context *context,
                                struct pci_dev *gpdev);
index fe6fc63251fec70e7cf2dee7f6deab47fe8ab256..38c5b4764bfed0e0aeb647418f53875bb0f7b2a0 100644 (file)
@@ -441,7 +441,6 @@ static int mce_handle_ierror(struct pt_regs *regs,
                                        if (pfn != ULONG_MAX) {
                                                *phys_addr =
                                                        (pfn << PAGE_SHIFT);
-                                               handled = 1;
                                        }
                                }
                        }
@@ -532,9 +531,7 @@ static int mce_handle_derror(struct pt_regs *regs,
                         * kernel/exception-64s.h
                         */
                        if (get_paca()->in_mce < MAX_MCE_DEPTH)
-                               if (!mce_find_instr_ea_and_pfn(regs, addr,
-                                                               phys_addr))
-                                       handled = 1;
+                               mce_find_instr_ea_and_pfn(regs, addr, phys_addr);
                }
                found = 1;
        }
@@ -572,7 +569,7 @@ static long mce_handle_error(struct pt_regs *regs,
                const struct mce_ierror_table itable[])
 {
        struct mce_error_info mce_err = { 0 };
-       uint64_t addr, phys_addr;
+       uint64_t addr, phys_addr = ULONG_MAX;
        uint64_t srr1 = regs->msr;
        long handled;
 
index e16ec7b3b427ea2d2ce2ca0a1229b16df51dc0e1..9ca7148b5881a098abf7bf0a3eff99536f99a7ec 100644 (file)
@@ -566,10 +566,35 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
 #endif
 
 #ifdef CONFIG_NMI_IPI
-static void stop_this_cpu(struct pt_regs *regs)
-#else
+static void nmi_stop_this_cpu(struct pt_regs *regs)
+{
+       /*
+        * This is a special case because it never returns, so the NMI IPI
+        * handling would never mark it as done, which makes any later
+        * smp_send_nmi_ipi() call spin forever. Mark it done now.
+        *
+        * IRQs are already hard disabled by the smp_handle_nmi_ipi.
+        */
+       nmi_ipi_lock();
+       nmi_ipi_busy_count--;
+       nmi_ipi_unlock();
+
+       /* Remove this CPU */
+       set_cpu_online(smp_processor_id(), false);
+
+       spin_begin();
+       while (1)
+               spin_cpu_relax();
+}
+
+void smp_send_stop(void)
+{
+       smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, nmi_stop_this_cpu, 1000000);
+}
+
+#else /* CONFIG_NMI_IPI */
+
 static void stop_this_cpu(void *dummy)
-#endif
 {
        /* Remove this CPU */
        set_cpu_online(smp_processor_id(), false);
@@ -582,12 +607,22 @@ static void stop_this_cpu(void *dummy)
 
 void smp_send_stop(void)
 {
-#ifdef CONFIG_NMI_IPI
-       smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, stop_this_cpu, 1000000);
-#else
+       static bool stopped = false;
+
+       /*
+        * Prevent waiting on csd lock from a previous smp_send_stop.
+        * This is racy, but in general callers try to do the right
+        * thing and only fire off one smp_send_stop (e.g., see
+        * kernel/panic.c)
+        */
+       if (stopped)
+               return;
+
+       stopped = true;
+
        smp_call_function(stop_this_cpu, NULL, 0);
-#endif
 }
+#endif /* CONFIG_NMI_IPI */
 
 struct thread_info *current_set[NR_CPUS];
 
index 6038e2e7aee03c2b29edb65624be370f01a6c928..876d4f294fdd89fc160439073a3c04c9c8e81174 100644 (file)
@@ -305,6 +305,13 @@ void kvmppc_core_queue_fpunavail(struct kvm_vcpu *vcpu)
        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_FP_UNAVAIL);
 }
 
+#ifdef CONFIG_ALTIVEC
+void kvmppc_core_queue_vec_unavail(struct kvm_vcpu *vcpu)
+{
+       kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_ALTIVEC_UNAVAIL);
+}
+#endif
+
 void kvmppc_core_queue_dec(struct kvm_vcpu *vcpu)
 {
        kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_DECREMENTER);
index 737f8a4632ccc68abfdd61a1900380834b125340..c3c39b02b2ba7b0ae58df5bf293103b382b2b708 100644 (file)
@@ -133,6 +133,7 @@ int __meminit arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *
                        start, start + size, rc);
                return -EFAULT;
        }
+       flush_inval_dcache_range(start, start + size);
 
        return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
 }
@@ -159,6 +160,7 @@ int __meminit arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap
 
        /* Remove htab bolted mappings for this section of memory */
        start = (unsigned long)__va(start);
+       flush_inval_dcache_range(start, start + size);
        ret = remove_section_mapping(start, start + size);
 
        /* Ensure all vmalloc mappings are flushed in case they also
index de470caf07848e28864cbb8ff0129e4ed7aaf021..fc222a0c2ac46b06095ed831827d40e84994e3ca 100644 (file)
@@ -82,19 +82,6 @@ static const struct file_operations memtrace_fops = {
        .open   = simple_open,
 };
 
-static void flush_memory_region(u64 base, u64 size)
-{
-       unsigned long line_size = ppc64_caches.l1d.size;
-       u64 end = base + size;
-       u64 addr;
-
-       base = round_down(base, line_size);
-       end = round_up(end, line_size);
-
-       for (addr = base; addr < end; addr += line_size)
-               asm volatile("dcbf 0,%0" : "=r" (addr) :: "memory");
-}
-
 static int check_memblock_online(struct memory_block *mem, void *arg)
 {
        if (mem->state != MEM_ONLINE)
@@ -132,10 +119,6 @@ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages)
        walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE,
                          change_memblock_state);
 
-       /* RCU grace period? */
-       flush_memory_region((u64)__va(start_pfn << PAGE_SHIFT),
-                           nr_pages << PAGE_SHIFT);
-
        lock_device_hotplug();
        remove_memory(nid, start_pfn << PAGE_SHIFT, nr_pages << PAGE_SHIFT);
        unlock_device_hotplug();
index 69a4f9e8bd554f137dd01b930b1b3d87e204fd47..525e966dce3418cef4a82f494da331793b628668 100644 (file)
 
 #define npu_to_phb(x) container_of(x, struct pnv_phb, npu)
 
+/*
+ * spinlock to protect initialisation of an npu_context for a particular
+ * mm_struct.
+ */
+static DEFINE_SPINLOCK(npu_context_lock);
+
+/*
+ * When an address shootdown range exceeds this threshold we invalidate the
+ * entire TLB on the GPU for the given PID rather than each specific address in
+ * the range.
+ */
+#define ATSD_THRESHOLD (2*1024*1024)
+
 /*
  * Other types of TCE cache invalidation are not functional in the
  * hardware.
@@ -401,7 +414,7 @@ struct npu_context {
        bool nmmu_flush;
 
        /* Callback to stop translation requests on a given GPU */
-       struct npu_context *(*release_cb)(struct npu_context *, void *);
+       void (*release_cb)(struct npu_context *context, void *priv);
 
        /*
         * Private pointer passed to the above callback for usage by
@@ -671,11 +684,19 @@ static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn,
        struct npu_context *npu_context = mn_to_npu_context(mn);
        unsigned long address;
 
-       for (address = start; address < end; address += PAGE_SIZE)
-               mmio_invalidate(npu_context, 1, address, false);
+       if (end - start > ATSD_THRESHOLD) {
+               /*
+                * Just invalidate the entire PID if the address range is too
+                * large.
+                */
+               mmio_invalidate(npu_context, 0, 0, true);
+       } else {
+               for (address = start; address < end; address += PAGE_SIZE)
+                       mmio_invalidate(npu_context, 1, address, false);
 
-       /* Do the flush only on the final addess == end */
-       mmio_invalidate(npu_context, 1, address, true);
+               /* Do the flush only on the final addess == end */
+               mmio_invalidate(npu_context, 1, address, true);
+       }
 }
 
 static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
@@ -696,11 +717,12 @@ static const struct mmu_notifier_ops nv_nmmu_notifier_ops = {
  * Returns an error if there no contexts are currently available or a
  * npu_context which should be passed to pnv_npu2_handle_fault().
  *
- * mmap_sem must be held in write mode.
+ * mmap_sem must be held in write mode and must not be called from interrupt
+ * context.
  */
 struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                        unsigned long flags,
-                       struct npu_context *(*cb)(struct npu_context *, void *),
+                       void (*cb)(struct npu_context *, void *),
                        void *priv)
 {
        int rc;
@@ -743,7 +765,9 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
        /*
         * Setup the NPU context table for a particular GPU. These need to be
         * per-GPU as we need the tables to filter ATSDs when there are no
-        * active contexts on a particular GPU.
+        * active contexts on a particular GPU. It is safe for these to be
+        * called concurrently with destroy as the OPAL call takes appropriate
+        * locks and refcounts on init/destroy.
         */
        rc = opal_npu_init_context(nphb->opal_id, mm->context.id, flags,
                                PCI_DEVID(gpdev->bus->number, gpdev->devfn));
@@ -754,8 +778,29 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
         * We store the npu pci device so we can more easily get at the
         * associated npus.
         */
+       spin_lock(&npu_context_lock);
        npu_context = mm->context.npu_context;
+       if (npu_context) {
+               if (npu_context->release_cb != cb ||
+                       npu_context->priv != priv) {
+                       spin_unlock(&npu_context_lock);
+                       opal_npu_destroy_context(nphb->opal_id, mm->context.id,
+                                               PCI_DEVID(gpdev->bus->number,
+                                                       gpdev->devfn));
+                       return ERR_PTR(-EINVAL);
+               }
+
+               WARN_ON(!kref_get_unless_zero(&npu_context->kref));
+       }
+       spin_unlock(&npu_context_lock);
+
        if (!npu_context) {
+               /*
+                * We can set up these fields without holding the
+                * npu_context_lock as the npu_context hasn't been returned to
+                * the caller meaning it can't be destroyed. Parallel allocation
+                * is protected against by mmap_sem.
+                */
                rc = -ENOMEM;
                npu_context = kzalloc(sizeof(struct npu_context), GFP_KERNEL);
                if (npu_context) {
@@ -774,8 +819,6 @@ struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev,
                }
 
                mm->context.npu_context = npu_context;
-       } else {
-               WARN_ON(!kref_get_unless_zero(&npu_context->kref));
        }
 
        npu_context->release_cb = cb;
@@ -814,15 +857,16 @@ static void pnv_npu2_release_context(struct kref *kref)
                mm_context_remove_copro(npu_context->mm);
 
        npu_context->mm->context.npu_context = NULL;
-       mmu_notifier_unregister(&npu_context->mn,
-                               npu_context->mm);
-
-       kfree(npu_context);
 }
 
+/*
+ * Destroy a context on the given GPU. May free the npu_context if it is no
+ * longer active on any GPUs. Must not be called from interrupt context.
+ */
 void pnv_npu2_destroy_context(struct npu_context *npu_context,
                        struct pci_dev *gpdev)
 {
+       int removed;
        struct pnv_phb *nphb;
        struct npu *npu;
        struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0);
@@ -844,7 +888,21 @@ void pnv_npu2_destroy_context(struct npu_context *npu_context,
        WRITE_ONCE(npu_context->npdev[npu->index][nvlink_index], NULL);
        opal_npu_destroy_context(nphb->opal_id, npu_context->mm->context.id,
                                PCI_DEVID(gpdev->bus->number, gpdev->devfn));
-       kref_put(&npu_context->kref, pnv_npu2_release_context);
+       spin_lock(&npu_context_lock);
+       removed = kref_put(&npu_context->kref, pnv_npu2_release_context);
+       spin_unlock(&npu_context_lock);
+
+       /*
+        * We need to do this outside of pnv_npu2_release_context so that it is
+        * outside the spinlock as mmu_notifier_destroy uses SRCU.
+        */
+       if (removed) {
+               mmu_notifier_unregister(&npu_context->mn,
+                                       npu_context->mm);
+
+               kfree(npu_context);
+       }
+
 }
 EXPORT_SYMBOL(pnv_npu2_destroy_context);
 
index f8868864f373ed5eecba333a5b1a2b83e38e0ec6..aa2a5139462ea5f6c81f51c8f025c9af84ce0be2 100644 (file)
@@ -48,10 +48,12 @@ unsigned long __init opal_get_boot_time(void)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       mdelay(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (rc == OPAL_BUSY)
-                       mdelay(10);
+               } else if (rc == OPAL_BUSY) {
+                       mdelay(OPAL_BUSY_DELAY_MS);
+               }
        }
        if (rc != OPAL_SUCCESS)
                return 0;
index 722951908b0a45c7dafd8a5861833b221ebe28d2..4f6676fe4bcc8981384928eec5a715f4d99e5225 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
index 1a0fa10cb6b721747b479651119b095d05893de0..32bae68e34c1b617c2e1547cbea9f609dc285d8f 100644 (file)
@@ -403,7 +403,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (err) {
                printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
                       dev_name(&vdev->dev), err);
-               kfree(vdev);
+               put_device(&vdev->dev);
                return NULL;
        }
        if (vdev->dp)
index 00fcf81f2c569b813a4b48f0800fc3ac72684d33..c07f492b871a8bf0f47cfb7be03a004dd740c2c1 100644 (file)
@@ -52,6 +52,7 @@ config X86
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select ARCH_HAS_ELF_RANDOMIZE
        select ARCH_HAS_FAST_MULTIPLIER
+       select ARCH_HAS_FILTER_PGPROT
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_HAS_KCOV                    if X86_64
@@ -273,6 +274,9 @@ config ARCH_HAS_CPU_RELAX
 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
 
+config ARCH_HAS_FILTER_PGPROT
+       def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
        def_bool y
 
index 9af927e59d49745757dd1bf07ad148df0db5a006..9de7f1e1dede7f6e6ebdc66e5f63756a173cdc0a 100644 (file)
@@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat)
        pushq   %rdx                    /* pt_regs->dx */
        pushq   %rcx                    /* pt_regs->cx */
        pushq   $-ENOSYS                /* pt_regs->ax */
-       pushq   $0                      /* pt_regs->r8  = 0 */
+       pushq   %r8                     /* pt_regs->r8 */
        xorl    %r8d, %r8d              /* nospec   r8 */
-       pushq   $0                      /* pt_regs->r9  = 0 */
+       pushq   %r9                     /* pt_regs->r9 */
        xorl    %r9d, %r9d              /* nospec   r9 */
-       pushq   $0                      /* pt_regs->r10 = 0 */
+       pushq   %r10                    /* pt_regs->r10 */
        xorl    %r10d, %r10d            /* nospec   r10 */
-       pushq   $0                      /* pt_regs->r11 = 0 */
+       pushq   %r11                    /* pt_regs->r11 */
        xorl    %r11d, %r11d            /* nospec   r11 */
        pushq   %rbx                    /* pt_regs->rbx */
        xorl    %ebx, %ebx              /* nospec   rbx */
index 607bf565a90c97c3d0d72bf979fdf88cf10c8e28..707b2a96e516b5579c9321cbf0822a627bc8a8d8 100644 (file)
@@ -3339,7 +3339,8 @@ static void intel_pmu_cpu_starting(int cpu)
 
        cpuc->lbr_sel = NULL;
 
-       flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
+       if (x86_pmu.version > 1)
+               flip_smm_bit(&x86_pmu.attr_freeze_on_smi);
 
        if (!cpuc->shared_regs)
                return;
@@ -3502,6 +3503,8 @@ static __initconst const struct x86_pmu core_pmu = {
        .cpu_dying              = intel_pmu_cpu_dying,
 };
 
+static struct attribute *intel_pmu_attrs[];
+
 static __initconst const struct x86_pmu intel_pmu = {
        .name                   = "Intel",
        .handle_irq             = intel_pmu_handle_irq,
@@ -3533,6 +3536,8 @@ static __initconst const struct x86_pmu intel_pmu = {
        .format_attrs           = intel_arch3_formats_attr,
        .events_sysfs_show      = intel_event_sysfs_show,
 
+       .attrs                  = intel_pmu_attrs,
+
        .cpu_prepare            = intel_pmu_cpu_prepare,
        .cpu_starting           = intel_pmu_cpu_starting,
        .cpu_dying              = intel_pmu_cpu_dying,
@@ -3911,8 +3916,6 @@ __init int intel_pmu_init(void)
 
        x86_pmu.max_pebs_events         = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
 
-
-       x86_pmu.attrs                   = intel_pmu_attrs;
        /*
         * Quirk: v2 perfmon does not report fixed-purpose events, so
         * assume at least 3 events, when not running in a hypervisor:
index d554c11e01ff46742d53148df0ffb9c3476e8d6e..578793e97431da25b0d5f3cbc20ae4c0655db075 100644 (file)
 #define X86_FEATURE_AVX512_VPOPCNTDQ   (16*32+14) /* POPCNT for vectors of DW/QW */
 #define X86_FEATURE_LA57               (16*32+16) /* 5-level page tables */
 #define X86_FEATURE_RDPID              (16*32+22) /* RDPID instruction */
+#define X86_FEATURE_CLDEMOTE           (16*32+25) /* CLDEMOTE instruction */
 
 /* AMD-defined CPU features, CPUID level 0x80000007 (EBX), word 17 */
 #define X86_FEATURE_OVERFLOW_RECOV     (17*32+ 0) /* MCA overflow recovery support */
index 404c5fdff859ded0e55325ac601ced0332910aac..548d90bbf919e8d75f9983a2cb97235637708bd8 100644 (file)
  * (0x80 is the syscall vector, 0x30-0x3f are for ISA)
  */
 #define FIRST_EXTERNAL_VECTOR          0x20
-/*
- * We start allocating at 0x21 to spread out vectors evenly between
- * priority levels. (0x80 is the syscall vector)
- */
-#define VECTOR_OFFSET_START            1
 
 /*
  * Reserve the lowest usable vector (and hence lowest priority)  0x20 for
 #define FIRST_SYSTEM_VECTOR            NR_VECTORS
 #endif
 
-#define FPU_IRQ                                  13
-
 /*
  * Size the maximum number of interrupts.
  *
index b885a961a150f079e38d4e5dbb8670ef9fde0b57..a34897aef2c295a8100716263d06153f1a1811e7 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL2.0 */
+/* SPDX-License-Identifier: GPL-2.0 */
 
 /*
  * Jailhouse paravirt detection
index 5f49b4ff0c248493f77cc12cadee0c2b6261c25d..f1633de5a675925b7b250e5b2e9e16b2ae6dd5e5 100644 (file)
@@ -601,6 +601,11 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+       return canon_pgprot(prot);
+}
+
 static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
                                         enum page_cache_mode pcm,
                                         enum page_cache_mode new_pcm)
index d5c21a38247570cf025b33ef2c6c203a9d3a4aef..adb47552e6bb700158788b4d42094f2d83931c86 100644 (file)
@@ -105,14 +105,14 @@ extern unsigned int ptrs_per_p4d;
 #define LDT_PGD_ENTRY          (pgtable_l5_enabled ? LDT_PGD_ENTRY_L5 : LDT_PGD_ENTRY_L4)
 #define LDT_BASE_ADDR          (LDT_PGD_ENTRY << PGDIR_SHIFT)
 
-#define __VMALLOC_BASE_L4      0xffffc90000000000
-#define __VMALLOC_BASE_L5      0xffa0000000000000
+#define __VMALLOC_BASE_L4      0xffffc90000000000UL
+#define __VMALLOC_BASE_L5      0xffa0000000000000UL
 
 #define VMALLOC_SIZE_TB_L4     32UL
 #define VMALLOC_SIZE_TB_L5     12800UL
 
-#define __VMEMMAP_BASE_L4      0xffffea0000000000
-#define __VMEMMAP_BASE_L5      0xffd4000000000000
+#define __VMEMMAP_BASE_L4      0xffffea0000000000UL
+#define __VMEMMAP_BASE_L5      0xffd4000000000000UL
 
 #ifdef CONFIG_DYNAMIC_MEMORY_LAYOUT
 # define VMALLOC_START         vmalloc_base
index 809134c644a677032e9eb2ae5d5a844806bc347e..90ab9a795b49329b5d06cdb45e15cb800a04ff63 100644 (file)
@@ -1 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_X64_MSGBUF_H
+#define __ASM_X64_MSGBUF_H
+
+#if !defined(__x86_64__) || !defined(__ILP32__)
 #include <asm-generic/msgbuf.h>
+#else
+/*
+ * The msqid64_ds structure for x86 architecture with x32 ABI.
+ *
+ * On x86-32 and x86-64 we can just use the generic definition, but
+ * x32 uses the same binary layout as x86_64, which is differnet
+ * from other 32-bit architectures.
+ */
+
+struct msqid64_ds {
+       struct ipc64_perm msg_perm;
+       __kernel_time_t msg_stime;      /* last msgsnd time */
+       __kernel_time_t msg_rtime;      /* last msgrcv time */
+       __kernel_time_t msg_ctime;      /* last change time */
+       __kernel_ulong_t msg_cbytes;    /* current number of bytes on queue */
+       __kernel_ulong_t msg_qnum;      /* number of messages in queue */
+       __kernel_ulong_t msg_qbytes;    /* max number of bytes on queue */
+       __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
+       __kernel_pid_t msg_lrpid;       /* last receive pid */
+       __kernel_ulong_t __unused4;
+       __kernel_ulong_t __unused5;
+};
+
+#endif
+
+#endif /* __ASM_GENERIC_MSGBUF_H */
index 83c05fc2de385c3260286bf12fed846617c8c095..644421f3823beefb16ddc83979fbdf01c15c6a7a 100644 (file)
@@ -1 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __ASM_X86_SHMBUF_H
+#define __ASM_X86_SHMBUF_H
+
+#if !defined(__x86_64__) || !defined(__ILP32__)
 #include <asm-generic/shmbuf.h>
+#else
+/*
+ * The shmid64_ds structure for x86 architecture with x32 ABI.
+ *
+ * On x86-32 and x86-64 we can just use the generic definition, but
+ * x32 uses the same binary layout as x86_64, which is differnet
+ * from other 32-bit architectures.
+ */
+
+struct shmid64_ds {
+       struct ipc64_perm       shm_perm;       /* operation perms */
+       size_t                  shm_segsz;      /* size of segment (bytes) */
+       __kernel_time_t         shm_atime;      /* last attach time */
+       __kernel_time_t         shm_dtime;      /* last detach time */
+       __kernel_time_t         shm_ctime;      /* last change time */
+       __kernel_pid_t          shm_cpid;       /* pid of creator */
+       __kernel_pid_t          shm_lpid;       /* pid of last operator */
+       __kernel_ulong_t        shm_nattch;     /* no. of current attaches */
+       __kernel_ulong_t        __unused4;
+       __kernel_ulong_t        __unused5;
+};
+
+struct shminfo64 {
+       __kernel_ulong_t        shmmax;
+       __kernel_ulong_t        shmmin;
+       __kernel_ulong_t        shmmni;
+       __kernel_ulong_t        shmseg;
+       __kernel_ulong_t        shmall;
+       __kernel_ulong_t        __unused1;
+       __kernel_ulong_t        __unused2;
+       __kernel_ulong_t        __unused3;
+       __kernel_ulong_t        __unused4;
+};
+
+#endif
+
+#endif /* __ASM_X86_SHMBUF_H */
index b9693b80fc219c74b29800d226777de3e6f3130e..60d1897041da89c19b97f03ca2c577102ec3186c 100644 (file)
@@ -835,6 +835,9 @@ static const struct _tlb_table intel_tlb_table[] = {
        { 0x5d, TLB_DATA_4K_4M,         256,    " TLB_DATA 4 KByte and 4 MByte pages" },
        { 0x61, TLB_INST_4K,            48,     " TLB_INST 4 KByte pages, full associative" },
        { 0x63, TLB_DATA_1G,            4,      " TLB_DATA 1 GByte pages, 4-way set associative" },
+       { 0x6b, TLB_DATA_4K,            256,    " TLB_DATA 4 KByte pages, 8-way associative" },
+       { 0x6c, TLB_DATA_2M_4M,         128,    " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
+       { 0x6d, TLB_DATA_1G,            16,     " TLB_DATA 1 GByte pages, fully associative" },
        { 0x76, TLB_INST_2M_4M,         8,      " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
        { 0xb0, TLB_INST_4K,            128,    " TLB_INST 4 KByte pages, 4-way set associative" },
        { 0xb1, TLB_INST_2M_4M,         4,      " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" },
index 10c4fc2c91f8ed1dd6879c8b0b8aa24d7275cd3b..77e201301528817e32537194cf5e075b29aa9686 100644 (file)
@@ -564,14 +564,12 @@ static int __reload_late(void *info)
        apply_microcode_local(&err);
        spin_unlock(&update_lock);
 
+       /* siblings return UCODE_OK because their engine got updated already */
        if (err > UCODE_NFOUND) {
                pr_warn("Error reloading microcode on CPU %d\n", cpu);
-               return -1;
-       /* siblings return UCODE_OK because their engine got updated already */
+               ret = -1;
        } else if (err == UCODE_UPDATED || err == UCODE_OK) {
                ret = 1;
-       } else {
-               return ret;
        }
 
        /*
index 32b8e5724f966abbc67153065dd17b5ddcfd6d70..1c2cfa0644aa979c97cc01a42925a44c25f9f852 100644 (file)
@@ -485,7 +485,6 @@ static void show_saved_mc(void)
  */
 static void save_mc_for_early(u8 *mc, unsigned int size)
 {
-#ifdef CONFIG_HOTPLUG_CPU
        /* Synchronization during CPU hotplug. */
        static DEFINE_MUTEX(x86_cpu_microcode_mutex);
 
@@ -495,7 +494,6 @@ static void save_mc_for_early(u8 *mc, unsigned int size)
        show_saved_mc();
 
        mutex_unlock(&x86_cpu_microcode_mutex);
-#endif
 }
 
 static bool load_builtin_intel_microcode(struct cpio_data *cp)
index fa183a131edc7b493dd86f47cf637ba42f15d274..a15fe0e92cf994be8a0d84284e6ee458c0f91e5a 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL2.0
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Jailhouse paravirt_ops implementation
  *
index 6285697b6e565c61611787f0a07274c2f3308630..5c623dfe39d159822f12602e2f1f7ae4d9024f6d 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/init_ohci1394_dma.h>
 #include <linux/kvm_para.h>
 #include <linux/dma-contiguous.h>
+#include <xen/xen.h>
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -534,6 +535,11 @@ static void __init reserve_crashkernel(void)
                high = true;
        }
 
+       if (xen_pv_domain()) {
+               pr_info("Ignoring crashkernel for a Xen PV domain\n");
+               return;
+       }
+
        /* 0 means: find the address automatically */
        if (crash_base <= 0) {
                /*
index 45175b81dd5b371e188820fddefcfd5ee6c8bee9..0f1cbb042f49b82e7a01b7ace0bce08061a8e6f1 100644 (file)
@@ -1571,6 +1571,8 @@ static inline void mwait_play_dead(void)
        void *mwait_ptr;
        int i;
 
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+               return;
        if (!this_cpu_has(X86_FEATURE_MWAIT))
                return;
        if (!this_cpu_has(X86_FEATURE_CLFLUSH))
index aa66ccd6ed6cc573b42a2584635f7f525dbe0713..c7668806163fd5ac493f59b6d9f08823828c7758 100644 (file)
@@ -4544,12 +4544,6 @@ static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
        __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa);
 }
 
-static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
-{
-       if (enable_ept)
-               vmx_flush_tlb(vcpu, true);
-}
-
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
 {
        ulong cr0_guest_owned_bits = vcpu->arch.cr0_guest_owned_bits;
@@ -9278,7 +9272,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
        } else {
                sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
                sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
        vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
 
@@ -9306,7 +9300,7 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
            !nested_cpu_has2(get_vmcs12(&vmx->vcpu),
                             SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
                vmcs_write64(APIC_ACCESS_ADDR, hpa);
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 }
 
@@ -11220,7 +11214,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                }
        } else if (nested_cpu_has2(vmcs12,
                                   SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 
        /*
@@ -12073,7 +12067,7 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
        } else if (!nested_cpu_has_ept(vmcs12) &&
                   nested_cpu_has2(vmcs12,
                                   SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) {
-               vmx_flush_tlb_ept_only(vcpu);
+               vmx_flush_tlb(vcpu, true);
        }
 
        /* This is needed for same reason as it was needed in prepare_vmcs02 */
index 7d35ce672989ddcbc719db96081d37607c79734f..c9492f7649020e2990b420e545e91470ec744e73 100644 (file)
@@ -302,13 +302,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
            __rem;                                              \
         })
 
-#define KVM_X86_DISABLE_EXITS_MWAIT          (1 << 0)
-#define KVM_X86_DISABLE_EXITS_HTL            (1 << 1)
-#define KVM_X86_DISABLE_EXITS_PAUSE          (1 << 2)
-#define KVM_X86_DISABLE_VALID_EXITS          (KVM_X86_DISABLE_EXITS_MWAIT | \
-                                              KVM_X86_DISABLE_EXITS_HTL | \
-                                              KVM_X86_DISABLE_EXITS_PAUSE)
-
 static inline bool kvm_mwait_in_guest(struct kvm *kvm)
 {
        return kvm->arch.mwait_in_guest;
index 0f3d50f4c48c5bc7e96f43b007870262245666e4..3bded76e8d5c5676bd972b0217e96fb84753ff7f 100644 (file)
@@ -93,6 +93,18 @@ void arch_report_meminfo(struct seq_file *m)
 static inline void split_page_count(int level) { }
 #endif
 
+static inline int
+within(unsigned long addr, unsigned long start, unsigned long end)
+{
+       return addr >= start && addr < end;
+}
+
+static inline int
+within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+{
+       return addr >= start && addr <= end;
+}
+
 #ifdef CONFIG_X86_64
 
 static inline unsigned long highmap_start_pfn(void)
@@ -106,20 +118,25 @@ static inline unsigned long highmap_end_pfn(void)
        return __pa_symbol(roundup(_brk_end, PMD_SIZE) - 1) >> PAGE_SHIFT;
 }
 
-#endif
-
-static inline int
-within(unsigned long addr, unsigned long start, unsigned long end)
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-       return addr >= start && addr < end;
+       /*
+        * Kernel text has an alias mapping at a high address, known
+        * here as "highmap".
+        */
+       return within_inclusive(pfn, highmap_start_pfn(), highmap_end_pfn());
 }
 
-static inline int
-within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
+#else
+
+static bool __cpa_pfn_in_highmap(unsigned long pfn)
 {
-       return addr >= start && addr <= end;
+       /* There is no highmap on 32-bit */
+       return false;
 }
 
+#endif
+
 /*
  * Flushing functions
  */
@@ -172,7 +189,7 @@ static void __cpa_flush_all(void *arg)
 
 static void cpa_flush_all(unsigned long cache)
 {
-       BUG_ON(irqs_disabled());
+       BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
        on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
@@ -236,7 +253,7 @@ static void cpa_flush_array(unsigned long *start, int numpages, int cache,
        unsigned long do_wbinvd = cache && numpages >= 1024; /* 4M threshold */
 #endif
 
-       BUG_ON(irqs_disabled());
+       BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
 
        on_each_cpu(__cpa_flush_all, (void *) do_wbinvd, 1);
 
@@ -1183,6 +1200,10 @@ static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr,
                cpa->numpages = 1;
                cpa->pfn = __pa(vaddr) >> PAGE_SHIFT;
                return 0;
+
+       } else if (__cpa_pfn_in_highmap(cpa->pfn)) {
+               /* Faults in the highmap are OK, so do not warn: */
+               return -EFAULT;
        } else {
                WARN(1, KERN_WARNING "CPA: called for zero pte. "
                        "vaddr = %lx cpa->vaddr = %lx\n", vaddr,
@@ -1335,8 +1356,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
         * to touch the high mapped kernel as well:
         */
        if (!within(vaddr, (unsigned long)_text, _brk_end) &&
-           within_inclusive(cpa->pfn, highmap_start_pfn(),
-                            highmap_end_pfn())) {
+           __cpa_pfn_in_highmap(cpa->pfn)) {
                unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) +
                                               __START_KERNEL_map - phys_base;
                alias_cpa = *cpa;
index f1fd52f449e00ce717f360fb833a26cd02769681..4d418e70587802b05aff3ae49e80db7faf47a64c 100644 (file)
@@ -421,6 +421,16 @@ static inline bool pti_kernel_image_global_ok(void)
        if (boot_cpu_has(X86_FEATURE_K8))
                return false;
 
+       /*
+        * RANDSTRUCT derives its hardening benefits from the
+        * attacker's lack of knowledge about the layout of kernel
+        * data structures.  Keep the kernel image non-global in
+        * cases where RANDSTRUCT is in use to help keep the layout a
+        * secret.
+        */
+       if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT))
+               return false;
+
        return true;
 }
 
@@ -430,12 +440,24 @@ static inline bool pti_kernel_image_global_ok(void)
  */
 void pti_clone_kernel_text(void)
 {
+       /*
+        * rodata is part of the kernel image and is normally
+        * readable on the filesystem or on the web.  But, do not
+        * clone the areas past rodata, they might contain secrets.
+        */
        unsigned long start = PFN_ALIGN(_text);
-       unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE);
+       unsigned long end = (unsigned long)__end_rodata_hpage_align;
 
        if (!pti_kernel_image_global_ok())
                return;
 
+       pr_debug("mapping partial kernel image into user address space\n");
+
+       /*
+        * Note that this will undo _some_ of the work that
+        * pti_set_kernel_image_nonglobal() did to clear the
+        * global bit.
+        */
        pti_clone_pmds(start, end, _PAGE_RW);
 }
 
@@ -458,8 +480,6 @@ void pti_set_kernel_image_nonglobal(void)
        if (pti_kernel_image_global_ok())
                return;
 
-       pr_debug("set kernel image non-global\n");
-
        set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT);
 }
 
index 1d5290c67108316f6495f33674094b5a476e2e14..0ee632bba06461021d7e4eb43127e7781a5114ee 100644 (file)
@@ -204,9 +204,14 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
 
        down_read(&crypto_alg_sem);
        alg = __crypto_alg_lookup(name, type | test, mask | test);
-       if (!alg && test)
-               alg = __crypto_alg_lookup(name, type, mask) ?
-                     ERR_PTR(-ELIBBAD) : NULL;
+       if (!alg && test) {
+               alg = __crypto_alg_lookup(name, type, mask);
+               if (alg && !crypto_is_larval(alg)) {
+                       /* Test failed */
+                       crypto_mod_put(alg);
+                       alg = ERR_PTR(-ELIBBAD);
+               }
+       }
        up_read(&crypto_alg_sem);
 
        return alg;
index 4faa2781c964e290f8b28e752993b9a408d927b4..466a112a4446820ff655c3b72076c86d3c7e4f2d 100644 (file)
@@ -1134,8 +1134,10 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
        if (!drbg)
                return;
        kzfree(drbg->Vbuf);
+       drbg->Vbuf = NULL;
        drbg->V = NULL;
        kzfree(drbg->Cbuf);
+       drbg->Cbuf = NULL;
        drbg->C = NULL;
        kzfree(drbg->scratchpadbuf);
        drbg->scratchpadbuf = NULL;
index 594c228d2f02112345ebc2ad345cd02a7e563a52..4a3ac31c07d0ee49615a00af001e49ff8e30f005 100644 (file)
@@ -69,11 +69,12 @@ static ssize_t driver_override_show(struct device *_dev,
                                    struct device_attribute *attr, char *buf)
 {
        struct amba_device *dev = to_amba_device(_dev);
+       ssize_t len;
 
-       if (!dev->driver_override)
-               return 0;
-
-       return sprintf(buf, "%s\n", dev->driver_override);
+       device_lock(_dev);
+       len = sprintf(buf, "%s\n", dev->driver_override);
+       device_unlock(_dev);
+       return len;
 }
 
 static ssize_t driver_override_store(struct device *_dev,
@@ -81,9 +82,10 @@ static ssize_t driver_override_store(struct device *_dev,
                                     const char *buf, size_t count)
 {
        struct amba_device *dev = to_amba_device(_dev);
-       char *driver_override, *old = dev->driver_override, *cp;
+       char *driver_override, *old, *cp;
 
-       if (count > PATH_MAX)
+       /* We need to keep extra room for a newline */
+       if (count >= (PAGE_SIZE - 1))
                return -EINVAL;
 
        driver_override = kstrndup(buf, count, GFP_KERNEL);
@@ -94,12 +96,15 @@ static ssize_t driver_override_store(struct device *_dev,
        if (cp)
                *cp = '\0';
 
+       device_lock(_dev);
+       old = dev->driver_override;
        if (strlen(driver_override)) {
                dev->driver_override = driver_override;
        } else {
               kfree(driver_override);
               dev->driver_override = NULL;
        }
+       device_unlock(_dev);
 
        kfree(old);
 
index 764b63a5aadefe5c73ef849ee5b377b134e3841e..e578eee315895d8c2783b933f5c252f5ec53824b 100644 (file)
@@ -2839,6 +2839,14 @@ static void binder_transaction(struct binder_proc *proc,
                        else
                                return_error = BR_DEAD_REPLY;
                        mutex_unlock(&context->context_mgr_node_lock);
+                       if (target_node && target_proc == proc) {
+                               binder_user_error("%d:%d got transaction to context manager from process owning it\n",
+                                                 proc->pid, thread->pid);
+                               return_error = BR_FAILED_REPLY;
+                               return_error_param = -EINVAL;
+                               return_error_line = __LINE__;
+                               goto err_invalid_target_handle;
+                       }
                }
                if (!target_node) {
                        /*
index 31b5015b59fecb456167e57ce697a4228bc77680..358354148decc4b4e49ff6df805426a2d72a63d4 100644 (file)
@@ -537,8 +537,8 @@ fw_create_instance(struct firmware *firmware, const char *fw_name,
 }
 
 /**
- * fw_load_sysfs_fallback - load a firmware via the syfs fallback mechanism
- * @fw_sysfs: firmware syfs information for the firmware to load
+ * fw_load_sysfs_fallback - load a firmware via the sysfs fallback mechanism
+ * @fw_sysfs: firmware sysfs information for the firmware to load
  * @opt_flags: flags of options, FW_OPT_*
  * @timeout: timeout to wait for the load
  *
index dfebc644ed35a1a410db821455ef54dcb8e025b6..f8255670a66352023225377e41d30b22bb35d1ea 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/device.h>
 
 /**
- * struct firmware_fallback_config - firmware fallback configuratioon settings
+ * struct firmware_fallback_config - firmware fallback configuration settings
  *
  * Helps describe and fine tune the fallback mechanism.
  *
index d1c0b60e9326f5f5a0b0db56ac7d328283f27506..6dc177bf4c42f6fce5b9787072aba2b7aa94e98c 100644 (file)
@@ -33,6 +33,7 @@ config HISILICON_LPC
        bool "Support for ISA I/O space on HiSilicon Hip06/7"
        depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
        select INDIRECT_PIO
+       select MFD_CORE if ACPI
        help
          Driver to enable I/O access to devices attached to the Low Pin
          Count bus on the HiSilicon Hip06/7 SoC.
index 0591874856d3c8ba037537bc863c4bbbfe21e0a5..54edaec1e60837dfcc515430012979482652271a 100644 (file)
@@ -679,6 +679,16 @@ void gpstate_timer_handler(struct timer_list *t)
 
        if (!spin_trylock(&gpstates->gpstate_lock))
                return;
+       /*
+        * If the timer has migrated to the different cpu then bring
+        * it back to one of the policy->cpus
+        */
+       if (!cpumask_test_cpu(raw_smp_processor_id(), policy->cpus)) {
+               gpstates->timer.expires = jiffies + msecs_to_jiffies(1);
+               add_timer_on(&gpstates->timer, cpumask_first(policy->cpus));
+               spin_unlock(&gpstates->gpstate_lock);
+               return;
+       }
 
        /*
         * If PMCR was last updated was using fast_swtich then
@@ -718,10 +728,8 @@ void gpstate_timer_handler(struct timer_list *t)
        if (gpstate_idx != gpstates->last_lpstate_idx)
                queue_gpstate_timer(gpstates);
 
+       set_pstate(&freq_data);
        spin_unlock(&gpstates->gpstate_lock);
-
-       /* Timer may get migrated to a different cpu on cpu hot unplug */
-       smp_call_function_any(policy->cpus, set_pstate, &freq_data, 1);
 }
 
 /*
index e6f17825db7942594e657ce9126b2e8612d45c86..2b90606452a2faf1a845b82bfd5bd9ce83b8bd00 100644 (file)
@@ -284,7 +284,7 @@ scmi_clock_info_get(const struct scmi_handle *handle, u32 clk_id)
        struct clock_info *ci = handle->clk_priv;
        struct scmi_clock_info *clk = ci->clk + clk_id;
 
-       if (!clk->name || !clk->name[0])
+       if (!clk->name[0])
                return NULL;
 
        return clk;
index 14f14efdf0d53ca23c24d7c514cdd4c4ad4b8174..06d212a3d49dd6ebdba471aa1814759ff828d1aa 100644 (file)
@@ -249,7 +249,7 @@ static int altera_ps_probe(struct spi_device *spi)
 
        conf->data = of_id->data;
        conf->spi = spi;
-       conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_HIGH);
+       conf->config = devm_gpiod_get(&spi->dev, "nconfig", GPIOD_OUT_LOW);
        if (IS_ERR(conf->config)) {
                dev_err(&spi->dev, "Failed to get config gpio: %ld\n",
                        PTR_ERR(conf->config));
index b0e591eaa71a21754e1e2246bf41df3cdd1936cf..e14263fca1c91472ead16fd5bfdceed0b11be81e 100644 (file)
@@ -1459,10 +1459,11 @@ static const u32 sgpr_init_compute_shader[] =
 static const u32 vgpr_init_regs[] =
 {
        mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0xffffffff,
-       mmCOMPUTE_RESOURCE_LIMITS, 0,
+       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
        mmCOMPUTE_NUM_THREAD_X, 256*4,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x100004f, /* VGPRS=15 (64 logical VGPRs), SGPRS=1 (16 SGPRs), BULKY=1 */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1479,10 +1480,11 @@ static const u32 vgpr_init_regs[] =
 static const u32 sgpr1_init_regs[] =
 {
        mmCOMPUTE_STATIC_THREAD_MGMT_SE0, 0x0f,
-       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000,
+       mmCOMPUTE_RESOURCE_LIMITS, 0x1000000, /* CU_GROUP_COUNT=1 */
        mmCOMPUTE_NUM_THREAD_X, 256*5,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
@@ -1503,6 +1505,7 @@ static const u32 sgpr2_init_regs[] =
        mmCOMPUTE_NUM_THREAD_X, 256*5,
        mmCOMPUTE_NUM_THREAD_Y, 1,
        mmCOMPUTE_NUM_THREAD_Z, 1,
+       mmCOMPUTE_PGM_RSRC1, 0x240, /* SGPRS=9 (80 GPRS) */
        mmCOMPUTE_PGM_RSRC2, 20,
        mmCOMPUTE_USER_DATA_0, 0xedcedc00,
        mmCOMPUTE_USER_DATA_1, 0xedcedc01,
index ed2f06c9f3462173d0d2f8cf2ce6a09e0a532e94..3858820a0055d31fb30621f55efa9067d8eebfd8 100644 (file)
@@ -6,5 +6,6 @@ config HSA_AMD
        tristate "HSA kernel driver for AMD GPU devices"
        depends on DRM_AMDGPU && X86_64
        imply AMD_IOMMU_V2
+       select MMU_NOTIFIER
        help
          Enable this if you want to use HSA features on AMD GPU devices.
index cd679cf1fd308fa5e436c6691399351e0f2f0c71..59808a39ecf4afb98587369384111948b4997adc 100644 (file)
@@ -749,12 +749,13 @@ static int kfd_ioctl_get_clock_counters(struct file *filep,
        struct timespec64 time;
 
        dev = kfd_device_by_id(args->gpu_id);
-       if (dev == NULL)
-               return -EINVAL;
-
-       /* Reading GPU clock counter from KGD */
-       args->gpu_clock_counter =
-               dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);
+       if (dev)
+               /* Reading GPU clock counter from KGD */
+               args->gpu_clock_counter =
+                       dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);
+       else
+               /* Node without GPU resource */
+               args->gpu_clock_counter = 0;
 
        /* No access to rdtsc. Using raw monotonic time */
        getrawmonotonic64(&time);
@@ -1147,7 +1148,7 @@ static int kfd_ioctl_acquire_vm(struct file *filep, struct kfd_process *p,
        return ret;
 }
 
-bool kfd_dev_is_large_bar(struct kfd_dev *dev)
+static bool kfd_dev_is_large_bar(struct kfd_dev *dev)
 {
        struct kfd_local_mem_info mem_info;
 
@@ -1421,7 +1422,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep,
 
        pdd = kfd_get_process_device_data(dev, p);
        if (!pdd) {
-               err = PTR_ERR(pdd);
+               err = -EINVAL;
                goto bind_process_to_device_failed;
        }
 
index 4e2f379ce2172c4a8b7925aec15873105f4b2c40..1dd1142246c25f0ef3a2b7cbae42bc534f86491e 100644 (file)
@@ -4557,6 +4557,7 @@ static int dm_update_crtcs_state(struct dc *dc,
                struct amdgpu_dm_connector *aconnector = NULL;
                struct drm_connector_state *new_con_state = NULL;
                struct dm_connector_state *dm_conn_state = NULL;
+               struct drm_plane_state *new_plane_state = NULL;
 
                new_stream = NULL;
 
@@ -4564,6 +4565,13 @@ static int dm_update_crtcs_state(struct dc *dc,
                dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
                acrtc = to_amdgpu_crtc(crtc);
 
+               new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary);
+
+               if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) {
+                       ret = -EINVAL;
+                       goto fail;
+               }
+
                aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
 
                /* TODO This hack should go away */
@@ -4760,7 +4768,7 @@ static int dm_update_planes_state(struct dc *dc,
                        if (!dm_old_crtc_state->stream)
                                continue;
 
-                       DRM_DEBUG_DRIVER("Disabling DRM plane: %d on DRM crtc %d\n",
+                       DRM_DEBUG_ATOMIC("Disabling DRM plane: %d on DRM crtc %d\n",
                                        plane->base.id, old_plane_crtc->base.id);
 
                        if (!dc_remove_plane_from_context(
index 490017df371de3bd1ae902f1794ea46d2c6a7a96..4be21bf5474981a8b954f4b1fb6b5c6a283cc82b 100644 (file)
@@ -329,14 +329,15 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
 {
        int src;
        struct irq_list_head *lh;
+       unsigned long irq_table_flags;
        DRM_DEBUG_KMS("DM_IRQ: releasing resources.\n");
-
        for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
-
+               DM_IRQ_TABLE_LOCK(adev, irq_table_flags);
                /* The handler was removed from the table,
                 * it means it is safe to flush all the 'work'
                 * (because no code can schedule a new one). */
                lh = &adev->dm.irq_handler_list_low_tab[src];
+               DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags);
                flush_work(&lh->work);
        }
 }
index 8291d74f26bcfd8934f424232297b7b60822268d..ace9ad578ca08f85aeccf49ac4d744b071444274 100644 (file)
@@ -161,6 +161,11 @@ dm_dp_mst_connector_destroy(struct drm_connector *connector)
        struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
        struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder;
 
+       if (amdgpu_dm_connector->edid) {
+               kfree(amdgpu_dm_connector->edid);
+               amdgpu_dm_connector->edid = NULL;
+       }
+
        drm_encoder_cleanup(&amdgpu_encoder->base);
        kfree(amdgpu_encoder);
        drm_connector_cleanup(connector);
@@ -181,28 +186,22 @@ static const struct drm_connector_funcs dm_dp_mst_connector_funcs = {
 void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
 {
        struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector);
-       struct edid *edid;
        struct dc_sink *dc_sink;
        struct dc_sink_init_data init_params = {
                        .link = aconnector->dc_link,
                        .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
 
+       /* FIXME none of this is safe. we shouldn't touch aconnector here in
+        * atomic_check
+        */
+
        /*
         * TODO: Need to further figure out why ddc.algo is NULL while MST port exists
         */
        if (!aconnector->port || !aconnector->port->aux.ddc.algo)
                return;
 
-       edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
-
-       if (!edid) {
-               drm_mode_connector_update_edid_property(
-                       &aconnector->base,
-                       NULL);
-               return;
-       }
-
-       aconnector->edid = edid;
+       ASSERT(aconnector->edid);
 
        dc_sink = dc_link_add_remote_sink(
                aconnector->dc_link,
@@ -215,9 +214,6 @@ void dm_dp_mst_dc_sink_create(struct drm_connector *connector)
 
        amdgpu_dm_add_sink_to_freesync_module(
                        connector, aconnector->edid);
-
-       drm_mode_connector_update_edid_property(
-                                       &aconnector->base, aconnector->edid);
 }
 
 static int dm_dp_mst_get_modes(struct drm_connector *connector)
@@ -230,10 +226,6 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
 
        if (!aconnector->edid) {
                struct edid *edid;
-               struct dc_sink *dc_sink;
-               struct dc_sink_init_data init_params = {
-                               .link = aconnector->dc_link,
-                               .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
                edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port);
 
                if (!edid) {
@@ -244,11 +236,17 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
                }
 
                aconnector->edid = edid;
+       }
 
+       if (!aconnector->dc_sink) {
+               struct dc_sink *dc_sink;
+               struct dc_sink_init_data init_params = {
+                               .link = aconnector->dc_link,
+                               .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST };
                dc_sink = dc_link_add_remote_sink(
                        aconnector->dc_link,
-                       (uint8_t *)edid,
-                       (edid->extensions + 1) * EDID_LENGTH,
+                       (uint8_t *)aconnector->edid,
+                       (aconnector->edid->extensions + 1) * EDID_LENGTH,
                        &init_params);
 
                dc_sink->priv = aconnector;
@@ -256,12 +254,12 @@ static int dm_dp_mst_get_modes(struct drm_connector *connector)
 
                if (aconnector->dc_sink)
                        amdgpu_dm_add_sink_to_freesync_module(
-                                       connector, edid);
-
-               drm_mode_connector_update_edid_property(
-                                               &aconnector->base, edid);
+                                       connector, aconnector->edid);
        }
 
+       drm_mode_connector_update_edid_property(
+                                       &aconnector->base, aconnector->edid);
+
        ret = drm_add_edid_modes(connector, aconnector->edid);
 
        return ret;
@@ -424,14 +422,6 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                dc_sink_release(aconnector->dc_sink);
                aconnector->dc_sink = NULL;
        }
-       if (aconnector->edid) {
-               kfree(aconnector->edid);
-               aconnector->edid = NULL;
-       }
-
-       drm_mode_connector_update_edid_property(
-                       &aconnector->base,
-                       NULL);
 
        aconnector->mst_connected = false;
 }
index 134069f364829030c8bbd7d7bf1e45b3c7340666..39f1db4acda4eaf1059be7071c1d48e384416193 100644 (file)
@@ -4451,6 +4451,7 @@ drm_reset_display_info(struct drm_connector *connector)
        info->max_tmds_clock = 0;
        info->dvi_dual = false;
        info->has_hdmi_infoframe = false;
+       memset(&info->hdmi, 0, sizeof(info->hdmi));
 
        info->non_desktop = 0;
 }
@@ -4462,17 +4463,11 @@ u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edi
 
        u32 quirks = edid_get_quirks(edid);
 
+       drm_reset_display_info(connector);
+
        info->width_mm = edid->width_cm * 10;
        info->height_mm = edid->height_cm * 10;
 
-       /* driver figures it out in this case */
-       info->bpc = 0;
-       info->color_formats = 0;
-       info->cea_rev = 0;
-       info->max_tmds_clock = 0;
-       info->dvi_dual = false;
-       info->has_hdmi_infoframe = false;
-
        info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
 
        DRM_DEBUG_KMS("non_desktop set to %d\n", info->non_desktop);
index fc8b2c6e35088410a61f81eb317bfaa09848d6cf..32d24c69da3c699a0dd3a0b88a99429a1db929f8 100644 (file)
@@ -2140,10 +2140,22 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
                }
        }
 
-       /* According to BSpec, "The CD clock frequency must be at least twice
+       /*
+        * According to BSpec, "The CD clock frequency must be at least twice
         * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
+        *
+        * FIXME: Check the actual, not default, BCLK being used.
+        *
+        * FIXME: This does not depend on ->has_audio because the higher CDCLK
+        * is required for audio probe, also when there are no audio capable
+        * displays connected at probe time. This leads to unnecessarily high
+        * CDCLK when audio is not required.
+        *
+        * FIXME: This limit is only applied when there are displays connected
+        * at probe time. If we probe without displays, we'll still end up using
+        * the platform minimum CDCLK, failing audio probe.
         */
-       if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
+       if (INTEL_GEN(dev_priv) >= 9)
                min_cdclk = max(2 * 96000, min_cdclk);
 
        /*
index d4368589b3553657e14adbcc9c54a56ed5f30865..a80fbad9be0fe4defd46c597d2e76f9b479228b4 100644 (file)
  * check the condition before the timeout.
  */
 #define __wait_for(OP, COND, US, Wmin, Wmax) ({ \
-       unsigned long timeout__ = jiffies + usecs_to_jiffies(US) + 1;   \
+       const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \
        long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \
        int ret__;                                                      \
        might_sleep();                                                  \
        for (;;) {                                                      \
-               bool expired__ = time_after(jiffies, timeout__);        \
+               const bool expired__ = ktime_after(ktime_get_raw(), end__); \
                OP;                                                     \
                if (COND) {                                             \
                        ret__ = 0;                                      \
index 6f12adc063650c1ad4f696922dee1215a98398c0..6467a5cc2ca30e1ac33cca2c2dc08177e886ae1a 100644 (file)
@@ -806,7 +806,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
                return;
 
        intel_fbdev_sync(ifbdev);
-       if (ifbdev->vma)
+       if (ifbdev->vma || ifbdev->helper.deferred_setup)
                drm_fb_helper_hotplug_event(&ifbdev->helper);
 }
 
index 53ea564f971ef6acd0ecf01d79254f2993450a78..66de4b2dc8b75c7f4faebd3c8d2f8af54c6a6871 100644 (file)
@@ -641,19 +641,18 @@ void skl_enable_dc6(struct drm_i915_private *dev_priv)
 
        DRM_DEBUG_KMS("Enabling DC6\n");
 
-       gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
+       /* Wa Display #1183: skl,kbl,cfl */
+       if (IS_GEN9_BC(dev_priv))
+               I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
+                          SKL_SELECT_ALTERNATE_DC_EXIT);
 
+       gen9_set_dc_state(dev_priv, DC_STATE_EN_UPTO_DC6);
 }
 
 void skl_disable_dc6(struct drm_i915_private *dev_priv)
 {
        DRM_DEBUG_KMS("Disabling DC6\n");
 
-       /* Wa Display #1183: skl,kbl,cfl */
-       if (IS_GEN9_BC(dev_priv))
-               I915_WRITE(GEN8_CHICKEN_DCPR_1, I915_READ(GEN8_CHICKEN_DCPR_1) |
-                          SKL_SELECT_ALTERNATE_DC_EXIT);
-
        gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
 }
 
index 6e5e1aa54ce19774340bd752785f25b8dcd20389..b001699297c486ab075a76bedd3c27d0c95572ee 100644 (file)
@@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
 
        spin_lock_irqsave(&dev->event_lock, flags);
        mdp4_crtc->event = crtc->state->event;
+       crtc->state->event = NULL;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        blend_setup(crtc);
index 9893e43ba6c5e530af187b1114f853f87c1fcd88..76b96081916f0b9567a8b021d890cd572cad0534 100644 (file)
@@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
 
        spin_lock_irqsave(&dev->event_lock, flags);
        mdp5_crtc->event = crtc->state->event;
+       crtc->state->event = NULL;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
        /*
index b4a8aa4490eed8ced3aaf167d4172331abcd5d4f..005760bee708ea5d0c59c1935df0b4224c334ee5 100644 (file)
@@ -171,7 +171,8 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
        return i;
 }
 
-const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format)
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
+               uint64_t modifier)
 {
        int i;
        for (i = 0; i < ARRAY_SIZE(formats); i++) {
index 1185487e7e5e36c6f208a9e6254a17aec1931700..4fa8dbe4e165cdd834ffc76d08949b073b3c61cf 100644 (file)
@@ -98,7 +98,7 @@ struct mdp_format {
 #define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
 
 uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
-const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format);
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
 
 /* MDP capabilities */
 #define MDP_CAP_SMP            BIT(0)  /* Shared Memory Pool                 */
index 7a03a94897088a474aa966ea86f778e5dde238e9..8baba30d6c659cfde69c52cd69b2adc3203c54a9 100644 (file)
@@ -173,6 +173,7 @@ struct msm_dsi_host {
 
        bool registered;
        bool power_on;
+       bool enabled;
        int irq;
 };
 
@@ -775,7 +776,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
        switch (mipi_fmt) {
        case MIPI_DSI_FMT_RGB888:       return CMD_DST_FORMAT_RGB888;
        case MIPI_DSI_FMT_RGB666_PACKED:
-       case MIPI_DSI_FMT_RGB666:       return VID_DST_FORMAT_RGB666;
+       case MIPI_DSI_FMT_RGB666:       return CMD_DST_FORMAT_RGB666;
        case MIPI_DSI_FMT_RGB565:       return CMD_DST_FORMAT_RGB565;
        default:                        return CMD_DST_FORMAT_RGB888;
        }
@@ -986,13 +987,19 @@ static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host)
 
 static void dsi_wait4video_done(struct msm_dsi_host *msm_host)
 {
+       u32 ret = 0;
+       struct device *dev = &msm_host->pdev->dev;
+
        dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1);
 
        reinit_completion(&msm_host->video_comp);
 
-       wait_for_completion_timeout(&msm_host->video_comp,
+       ret = wait_for_completion_timeout(&msm_host->video_comp,
                        msecs_to_jiffies(70));
 
+       if (ret <= 0)
+               dev_err(dev, "wait for video done timed out\n");
+
        dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0);
 }
 
@@ -1001,7 +1008,7 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
        if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
                return;
 
-       if (msm_host->power_on) {
+       if (msm_host->power_on && msm_host->enabled) {
                dsi_wait4video_done(msm_host);
                /* delay 4 ms to skip BLLP */
                usleep_range(2000, 4000);
@@ -2203,7 +2210,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host *host)
         *      pm_runtime_put_autosuspend(&msm_host->pdev->dev);
         * }
         */
-
+       msm_host->enabled = true;
        return 0;
 }
 
@@ -2211,6 +2218,7 @@ int msm_dsi_host_disable(struct mipi_dsi_host *host)
 {
        struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
 
+       msm_host->enabled = false;
        dsi_op_mode_config(msm_host,
                !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false);
 
index 8e9d5c255820272ebe0a759ed51e4aa0ee6047b9..9a9fa0c75a131083f32c57f5cd89a0e02c7b87d1 100644 (file)
@@ -265,6 +265,115 @@ int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
        return 0;
 }
 
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+       struct msm_dsi_phy_clk_request *clk_req)
+{
+       const unsigned long bit_rate = clk_req->bitclk_rate;
+       const unsigned long esc_rate = clk_req->escclk_rate;
+       s32 ui, ui_x8, lpx;
+       s32 tmax, tmin;
+       s32 pcnt0 = 50;
+       s32 pcnt1 = 50;
+       s32 pcnt2 = 10;
+       s32 pcnt3 = 30;
+       s32 pcnt4 = 10;
+       s32 pcnt5 = 2;
+       s32 coeff = 1000; /* Precision, should avoid overflow */
+       s32 hb_en, hb_en_ckln;
+       s32 temp;
+
+       if (!bit_rate || !esc_rate)
+               return -EINVAL;
+
+       timing->hs_halfbyte_en = 0;
+       hb_en = 0;
+       timing->hs_halfbyte_en_ckln = 0;
+       hb_en_ckln = 0;
+
+       ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+       ui_x8 = ui << 3;
+       lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
+
+       temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
+       tmin = max_t(s32, temp, 0);
+       temp = (95 * coeff) / ui_x8;
+       tmax = max_t(s32, temp, 0);
+       timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
+
+       temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = (tmin > 255) ? 511 : 255;
+       timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
+
+       tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
+       temp = 105 * coeff + 12 * ui - 20 * coeff;
+       tmax = (temp + 3 * ui) / ui_x8;
+       timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+       temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
+       tmin = max_t(s32, temp, 0);
+       temp = (85 * coeff + 6 * ui) / ui_x8;
+       tmax = max_t(s32, temp, 0);
+       timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
+
+       temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 255;
+       timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
+
+       tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
+       temp = 105 * coeff + 12 * ui - 20 * coeff;
+       tmax = (temp / ui_x8) - 1;
+       timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+       temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
+       timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
+
+       tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
+       tmax = 255;
+       timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
+
+       temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
+       timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
+
+       temp = 60 * coeff + 52 * ui - 43 * ui;
+       tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 63;
+       timing->shared_timings.clk_post =
+               linear_inter(tmax, tmin, pcnt2, 0, false);
+
+       temp = 8 * ui + (timing->clk_prepare << 3) * ui;
+       temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
+       temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
+               (((timing->hs_rqst_ckln << 3) + 8) * ui);
+       tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+       tmax = 63;
+       if (tmin > tmax) {
+               temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
+               timing->shared_timings.clk_pre = temp >> 1;
+               timing->shared_timings.clk_pre_inc_by_2 = 1;
+       } else {
+               timing->shared_timings.clk_pre =
+                       linear_inter(tmax, tmin, pcnt2, 0, false);
+                       timing->shared_timings.clk_pre_inc_by_2 = 0;
+       }
+
+       timing->ta_go = 3;
+       timing->ta_sure = 0;
+       timing->ta_get = 4;
+
+       DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+               timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+               timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
+               timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+               timing->hs_zero, timing->hs_prepare, timing->hs_trail,
+               timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
+               timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
+               timing->hs_prep_dly_ckln);
+
+       return 0;
+}
+
 void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
                                u32 bit_mask)
 {
index c56268cbdb3d81925410be764515d0f6be8a9864..a24ab80994a3c08710723f6a0325512785196a84 100644 (file)
@@ -101,6 +101,8 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
                             struct msm_dsi_phy_clk_request *clk_req);
 int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
                                struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+                               struct msm_dsi_phy_clk_request *clk_req);
 void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg,
                                u32 bit_mask);
 int msm_dsi_phy_init_common(struct msm_dsi_phy *phy);
index 0af951aaeea1e2d563d4bd2238241e87791a65f7..b3fffc8dbb2ab572aa688aabe8ef4546728e3fb8 100644 (file)
@@ -79,34 +79,6 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
        dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
 }
 
-static int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
-                                      struct msm_dsi_phy_clk_request *clk_req)
-{
-       /*
-        * TODO: These params need to be computed, they're currently hardcoded
-        * for a 1440x2560@60Hz panel with a byteclk of 100.618 Mhz, and a
-        * default escape clock of 19.2 Mhz.
-        */
-
-       timing->hs_halfbyte_en = 0;
-       timing->clk_zero = 0x1c;
-       timing->clk_prepare = 0x07;
-       timing->clk_trail = 0x07;
-       timing->hs_exit = 0x23;
-       timing->hs_zero = 0x21;
-       timing->hs_prepare = 0x07;
-       timing->hs_trail = 0x07;
-       timing->hs_rqst = 0x05;
-       timing->ta_sure = 0x00;
-       timing->ta_go = 0x03;
-       timing->ta_get = 0x04;
-
-       timing->shared_timings.clk_pre = 0x2d;
-       timing->shared_timings.clk_post = 0x0d;
-
-       return 0;
-}
-
 static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
                               struct msm_dsi_phy_clk_request *clk_req)
 {
index 0e0c87252ab07c9777cd5f623e71d92c86ea0175..7a16242bf8bf28bb5d7493fb47ded89c754f7092 100644 (file)
@@ -183,7 +183,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
        hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
        vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
 
-       format = kms->funcs->get_format(kms, mode_cmd->pixel_format);
+       format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
+                       mode_cmd->modifier[0]);
        if (!format) {
                dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
                                (char *)&mode_cmd->pixel_format);
index c178563fcd4dc56a2d1fbdaf4197c847b5c11904..456622b4633558b7d0d98a1d57729aac9d33c57f 100644 (file)
@@ -92,8 +92,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 
        if (IS_ERR(fb)) {
                dev_err(dev->dev, "failed to allocate fb\n");
-               ret = PTR_ERR(fb);
-               goto fail;
+               return PTR_ERR(fb);
        }
 
        bo = msm_framebuffer_bo(fb, 0);
@@ -151,13 +150,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 
 fail_unlock:
        mutex_unlock(&dev->struct_mutex);
-fail:
-
-       if (ret) {
-               if (fb)
-                       drm_framebuffer_remove(fb);
-       }
-
+       drm_framebuffer_remove(fb);
        return ret;
 }
 
index 95196479f651b18697229765432a0493f6b7d4ce..f583bb4222f9ad13dc17d74ec13d65ad16734506 100644 (file)
@@ -132,17 +132,19 @@ static void put_pages(struct drm_gem_object *obj)
        struct msm_gem_object *msm_obj = to_msm_bo(obj);
 
        if (msm_obj->pages) {
-               /* For non-cached buffers, ensure the new pages are clean
-                * because display controller, GPU, etc. are not coherent:
-                */
-               if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-                       dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
-                                       msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+               if (msm_obj->sgt) {
+                       /* For non-cached buffers, ensure the new
+                        * pages are clean because display controller,
+                        * GPU, etc. are not coherent:
+                        */
+                       if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
+                               dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
+                                            msm_obj->sgt->nents,
+                                            DMA_BIDIRECTIONAL);
 
-               if (msm_obj->sgt)
                        sg_free_table(msm_obj->sgt);
-
-               kfree(msm_obj->sgt);
+                       kfree(msm_obj->sgt);
+               }
 
                if (use_pages(obj))
                        drm_gem_put_pages(obj, msm_obj->pages, true, false);
index 17d5824417ad32a0fbddaf94069a0bb453c8403c..aaa329dc020ece445a5334329ae8ab34f68c8035 100644 (file)
@@ -48,8 +48,11 @@ struct msm_kms_funcs {
        /* functions to wait for atomic commit completed on each CRTC */
        void (*wait_for_crtc_commit_done)(struct msm_kms *kms,
                                        struct drm_crtc *crtc);
+       /* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
+       const struct msm_format *(*get_format)(struct msm_kms *kms,
+                                       const uint32_t format,
+                                       const uint64_t modifiers);
        /* misc: */
-       const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
        long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
                        struct drm_encoder *encoder);
        int (*set_split_display)(struct msm_kms *kms,
index c0fb52c6d4caaae43753a387f2fa5898019524db..01665b98c57e18cd2bf5c59323e1df9e95702aff 100644 (file)
@@ -179,10 +179,9 @@ qxl_push_command_ring_release(struct qxl_device *qdev, struct qxl_release *relea
                              uint32_t type, bool interruptible)
 {
        struct qxl_command cmd;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
        cmd.type = type;
-       cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
+       cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
 
        return qxl_ring_push(qdev->command_ring, &cmd, interruptible);
 }
@@ -192,10 +191,9 @@ qxl_push_cursor_ring_release(struct qxl_device *qdev, struct qxl_release *releas
                             uint32_t type, bool interruptible)
 {
        struct qxl_command cmd;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
 
        cmd.type = type;
-       cmd.data = qxl_bo_physical_address(qdev, to_qxl_bo(entry->tv.bo), release->release_offset);
+       cmd.data = qxl_bo_physical_address(qdev, release->release_bo, release->release_offset);
 
        return qxl_ring_push(qdev->cursor_ring, &cmd, interruptible);
 }
index 00a1a66b052a5c31fe925bebb4800155013e3897..864b456080c4bf9262121e2e0bbee51a47272a07 100644 (file)
@@ -167,6 +167,7 @@ struct qxl_release {
 
        int id;
        int type;
+       struct qxl_bo *release_bo;
        uint32_t release_offset;
        uint32_t surface_release_id;
        struct ww_acquire_ctx ticket;
index e238a1a2eca1cf47c88248ff3b7419579055a5bc..6cc9f3367fa05581a90280b7cc111259cc2692fa 100644 (file)
@@ -182,9 +182,9 @@ static int qxl_process_single_command(struct qxl_device *qdev,
                goto out_free_reloc;
 
        /* TODO copy slow path code from i915 */
-       fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_SIZE));
+       fb_cmd = qxl_bo_kmap_atomic_page(qdev, cmd_bo, (release->release_offset & PAGE_MASK));
        unwritten = __copy_from_user_inatomic_nocache
-               (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_SIZE),
+               (fb_cmd + sizeof(union qxl_release_info) + (release->release_offset & ~PAGE_MASK),
                 u64_to_user_ptr(cmd->command), cmd->command_size);
 
        {
index 5d84a66fed3638144917124a02c68dfd420a2baa..7cb214577275ba76ab0b6045e5863394f1ebb5f9 100644 (file)
@@ -173,6 +173,7 @@ qxl_release_free_list(struct qxl_release *release)
                list_del(&entry->tv.head);
                kfree(entry);
        }
+       release->release_bo = NULL;
 }
 
 void
@@ -296,7 +297,6 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
 {
        if (surface_cmd_type == QXL_SURFACE_CMD_DESTROY && create_rel) {
                int idr_ret;
-               struct qxl_bo_list *entry = list_first_entry(&create_rel->bos, struct qxl_bo_list, tv.head);
                struct qxl_bo *bo;
                union qxl_release_info *info;
 
@@ -304,8 +304,9 @@ int qxl_alloc_surface_release_reserved(struct qxl_device *qdev,
                idr_ret = qxl_release_alloc(qdev, QXL_RELEASE_SURFACE_CMD, release);
                if (idr_ret < 0)
                        return idr_ret;
-               bo = to_qxl_bo(entry->tv.bo);
+               bo = create_rel->release_bo;
 
+               (*release)->release_bo = bo;
                (*release)->release_offset = create_rel->release_offset + 64;
 
                qxl_release_list_add(*release, bo);
@@ -365,6 +366,7 @@ int qxl_alloc_release_reserved(struct qxl_device *qdev, unsigned long size,
 
        bo = qxl_bo_ref(qdev->current_release_bo[cur_idx]);
 
+       (*release)->release_bo = bo;
        (*release)->release_offset = qdev->current_release_bo_offset[cur_idx] * release_size_per_bo[cur_idx];
        qdev->current_release_bo_offset[cur_idx]++;
 
@@ -408,13 +410,12 @@ union qxl_release_info *qxl_release_map(struct qxl_device *qdev,
 {
        void *ptr;
        union qxl_release_info *info;
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
-       struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
+       struct qxl_bo *bo = release->release_bo;
 
-       ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_SIZE);
+       ptr = qxl_bo_kmap_atomic_page(qdev, bo, release->release_offset & PAGE_MASK);
        if (!ptr)
                return NULL;
-       info = ptr + (release->release_offset & ~PAGE_SIZE);
+       info = ptr + (release->release_offset & ~PAGE_MASK);
        return info;
 }
 
@@ -422,11 +423,10 @@ void qxl_release_unmap(struct qxl_device *qdev,
                       struct qxl_release *release,
                       union qxl_release_info *info)
 {
-       struct qxl_bo_list *entry = list_first_entry(&release->bos, struct qxl_bo_list, tv.head);
-       struct qxl_bo *bo = to_qxl_bo(entry->tv.bo);
+       struct qxl_bo *bo = release->release_bo;
        void *ptr;
 
-       ptr = ((void *)info) - (release->release_offset & ~PAGE_SIZE);
+       ptr = ((void *)info) - (release->release_offset & ~PAGE_MASK);
        qxl_bo_kunmap_atomic_page(qdev, bo, ptr);
 }
 
index bffff4c9fbf56f92dc8a3b566c33e266c729fb95..be3f14d7746deee1b0183c113dc653e4c7e3629d 100644 (file)
@@ -94,64 +94,9 @@ static void sun4i_lvds_encoder_disable(struct drm_encoder *encoder)
        }
 }
 
-static enum drm_mode_status sun4i_lvds_encoder_mode_valid(struct drm_encoder *crtc,
-                                                         const struct drm_display_mode *mode)
-{
-       struct sun4i_lvds *lvds = drm_encoder_to_sun4i_lvds(crtc);
-       struct sun4i_tcon *tcon = lvds->tcon;
-       u32 hsync = mode->hsync_end - mode->hsync_start;
-       u32 vsync = mode->vsync_end - mode->vsync_start;
-       unsigned long rate = mode->clock * 1000;
-       long rounded_rate;
-
-       DRM_DEBUG_DRIVER("Validating modes...\n");
-
-       if (hsync < 1)
-               return MODE_HSYNC_NARROW;
-
-       if (hsync > 0x3ff)
-               return MODE_HSYNC_WIDE;
-
-       if ((mode->hdisplay < 1) || (mode->htotal < 1))
-               return MODE_H_ILLEGAL;
-
-       if ((mode->hdisplay > 0x7ff) || (mode->htotal > 0xfff))
-               return MODE_BAD_HVALUE;
-
-       DRM_DEBUG_DRIVER("Horizontal parameters OK\n");
-
-       if (vsync < 1)
-               return MODE_VSYNC_NARROW;
-
-       if (vsync > 0x3ff)
-               return MODE_VSYNC_WIDE;
-
-       if ((mode->vdisplay < 1) || (mode->vtotal < 1))
-               return MODE_V_ILLEGAL;
-
-       if ((mode->vdisplay > 0x7ff) || (mode->vtotal > 0xfff))
-               return MODE_BAD_VVALUE;
-
-       DRM_DEBUG_DRIVER("Vertical parameters OK\n");
-
-       tcon->dclk_min_div = 7;
-       tcon->dclk_max_div = 7;
-       rounded_rate = clk_round_rate(tcon->dclk, rate);
-       if (rounded_rate < rate)
-               return MODE_CLOCK_LOW;
-
-       if (rounded_rate > rate)
-               return MODE_CLOCK_HIGH;
-
-       DRM_DEBUG_DRIVER("Clock rate OK\n");
-
-       return MODE_OK;
-}
-
 static const struct drm_encoder_helper_funcs sun4i_lvds_enc_helper_funcs = {
        .disable        = sun4i_lvds_encoder_disable,
        .enable         = sun4i_lvds_encoder_enable,
-       .mode_valid     = sun4i_lvds_encoder_mode_valid,
 };
 
 static const struct drm_encoder_funcs sun4i_lvds_enc_funcs = {
index 48e4f1df6e5d933bb5e4204a8866139a70de7f70..020070d483d350a58695c7fa9f21f7c2be4db463 100644 (file)
@@ -293,7 +293,7 @@ static int virtio_gpu_queue_ctrl_buffer_locked(struct virtio_gpu_device *vgdev,
        ret = virtqueue_add_sgs(vq, sgs, outcnt, incnt, vbuf, GFP_ATOMIC);
        if (ret == -ENOSPC) {
                spin_unlock(&vgdev->ctrlq.qlock);
-               wait_event(vgdev->ctrlq.ack_queue, vq->num_free);
+               wait_event(vgdev->ctrlq.ack_queue, vq->num_free >= outcnt + incnt);
                spin_lock(&vgdev->ctrlq.qlock);
                goto retry;
        } else {
@@ -368,7 +368,7 @@ static int virtio_gpu_queue_cursor(struct virtio_gpu_device *vgdev,
        ret = virtqueue_add_sgs(vq, sgs, outcnt, 0, vbuf, GFP_ATOMIC);
        if (ret == -ENOSPC) {
                spin_unlock(&vgdev->cursorq.qlock);
-               wait_event(vgdev->cursorq.ack_queue, vq->num_free);
+               wait_event(vgdev->cursorq.ack_queue, vq->num_free >= outcnt);
                spin_lock(&vgdev->cursorq.qlock);
                goto retry;
        } else {
index c4865b08d7fb9e3b194dba2830b837fe6ab17819..8d21b9825d71764dc950a47dec4a3bc3dc102e25 100644 (file)
@@ -707,7 +707,6 @@ config I2C_MPC
 config I2C_MT65XX
        tristate "MediaTek I2C adapter"
        depends on ARCH_MEDIATEK || COMPILE_TEST
-       depends on HAS_DMA
        help
          This selects the MediaTek(R) Integrated Inter Circuit bus driver
          for MT65xx and MT81xx.
@@ -885,7 +884,6 @@ config I2C_SH7760
 
 config I2C_SH_MOBILE
        tristate "SuperH Mobile I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
@@ -1098,7 +1096,6 @@ config I2C_XLP9XX
 
 config I2C_RCAR
        tristate "Renesas R-Car I2C Controller"
-       depends on HAS_DMA
        depends on ARCH_RENESAS || COMPILE_TEST
        select I2C_SLAVE
        help
index 25fcc3c1e32bf3d9a41fa345982039fb234dbcbd..4053259bccb8d704d9d386287086841690174844 100644 (file)
@@ -86,6 +86,7 @@ struct sprd_i2c {
        u32 count;
        int irq;
        int err;
+       bool is_suspended;
 };
 
 static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
@@ -283,6 +284,9 @@ static int sprd_i2c_master_xfer(struct i2c_adapter *i2c_adap,
        struct sprd_i2c *i2c_dev = i2c_adap->algo_data;
        int im, ret;
 
+       if (i2c_dev->is_suspended)
+               return -EBUSY;
+
        ret = pm_runtime_get_sync(i2c_dev->dev);
        if (ret < 0)
                return ret;
@@ -364,13 +368,12 @@ static irqreturn_t sprd_i2c_isr_thread(int irq, void *dev_id)
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we got one ACK from slave when writing data, and we did not
@@ -408,14 +411,13 @@ static irqreturn_t sprd_i2c_isr(int irq, void *dev_id)
 {
        struct sprd_i2c *i2c_dev = dev_id;
        struct i2c_msg *msg = i2c_dev->msg;
-       u32 i2c_count = readl(i2c_dev->base + I2C_COUNT);
        bool ack = !(readl(i2c_dev->base + I2C_STATUS) & I2C_RX_ACK);
        u32 i2c_tran;
 
        if (msg->flags & I2C_M_RD)
                i2c_tran = i2c_dev->count >= I2C_FIFO_FULL_THLD;
        else
-               i2c_tran = i2c_count;
+               i2c_tran = i2c_dev->count;
 
        /*
         * If we did not get one ACK from slave when writing data, then we
@@ -586,11 +588,23 @@ static int sprd_i2c_remove(struct platform_device *pdev)
 
 static int __maybe_unused sprd_i2c_suspend_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = true;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_suspend(pdev);
 }
 
 static int __maybe_unused sprd_i2c_resume_noirq(struct device *pdev)
 {
+       struct sprd_i2c *i2c_dev = dev_get_drvdata(pdev);
+
+       i2c_lock_adapter(&i2c_dev->adap);
+       i2c_dev->is_suspended = false;
+       i2c_unlock_adapter(&i2c_dev->adap);
+
        return pm_runtime_force_resume(pdev);
 }
 
index 036a03f0d0a6866001d0badd11cb9b30516ca5de..1667b6e7674f4a0439befcd544d74753e41d43f3 100644 (file)
@@ -280,7 +280,7 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
                 */
                if (msgs[i].flags & I2C_M_RECV_LEN) {
                        if (!(msgs[i].flags & I2C_M_RD) ||
-                           msgs[i].buf[0] < 1 ||
+                           msgs[i].len < 1 || msgs[i].buf[0] < 1 ||
                            msgs[i].len < msgs[i].buf[0] +
                                             I2C_SMBUS_BLOCK_MAX) {
                                res = -EINVAL;
index 46115a39209821830c1a3789d1cb93d67ff35746..c81c79d01d93078fb2a4357e6f0c51aea6a2b12b 100644 (file)
@@ -31,6 +31,7 @@
 enum evdev_clock_type {
        EV_CLK_REAL = 0,
        EV_CLK_MONO,
+       EV_CLK_BOOT,
        EV_CLK_MAX
 };
 
@@ -197,10 +198,12 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
        case CLOCK_REALTIME:
                clk_type = EV_CLK_REAL;
                break;
-       case CLOCK_BOOTTIME:
        case CLOCK_MONOTONIC:
                clk_type = EV_CLK_MONO;
                break;
+       case CLOCK_BOOTTIME:
+               clk_type = EV_CLK_BOOT;
+               break;
        default:
                return -EINVAL;
        }
@@ -311,6 +314,8 @@ static void evdev_events(struct input_handle *handle,
 
        ev_time[EV_CLK_MONO] = ktime_get();
        ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
+       ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
+                                                TK_OFFS_BOOT);
 
        rcu_read_lock();
 
index 71a89d5d3efd773f03bbf2359b91b1fa292619f2..db8043019ec62f9a1cb589bf1e523e43050db419 100644 (file)
 
 int main(void)
 {
-       DEFINE(EMIF_SDCFG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_sdcfg_val));
-       DEFINE(EMIF_TIMING1_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing1_val));
-       DEFINE(EMIF_TIMING2_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing2_val));
-       DEFINE(EMIF_TIMING3_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_timing3_val));
-       DEFINE(EMIF_REF_CTRL_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ref_ctrl_val));
-       DEFINE(EMIF_ZQCFG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_zqcfg_val));
-       DEFINE(EMIF_PMCR_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_pmcr_val));
-       DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val));
-       DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl));
-       DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh));
-       DEFINE(EMIF_COS_CONFIG_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_cos_config));
-       DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping));
-       DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map));
-       DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map));
-       DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ocp_config_val));
-       DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim));
-       DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw));
-       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val));
-       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw));
-       DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1));
-       DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET,
-              offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals));
-       DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3));
-
-       BLANK();
-
-       DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt));
-       DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys));
-       DEFINE(EMIF_PM_CONFIG_OFFSET,
-              offsetof(struct ti_emif_pm_data, ti_emif_sram_config));
-       DEFINE(EMIF_PM_REGS_VIRT_OFFSET,
-              offsetof(struct ti_emif_pm_data, regs_virt));
-       DEFINE(EMIF_PM_REGS_PHYS_OFFSET,
-              offsetof(struct ti_emif_pm_data, regs_phys));
-       DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data));
-
-       BLANK();
-
-       DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET,
-              offsetof(struct ti_emif_pm_functions, save_context));
-       DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET,
-              offsetof(struct ti_emif_pm_functions, restore_context));
-       DEFINE(EMIF_PM_ENTER_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, enter_sr));
-       DEFINE(EMIF_PM_EXIT_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, exit_sr));
-       DEFINE(EMIF_PM_ABORT_SR_OFFSET,
-              offsetof(struct ti_emif_pm_functions, abort_sr));
-       DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions));
+       ti_emif_asm_offsets();
 
        return 0;
 }
index d4c07b85f18e598ef8c0f85e8ce6fd70c9709396..f5695be14499855a2a54071004e8107c3289f680 100644 (file)
@@ -45,6 +45,7 @@
 #define I82802AB       0x00ad
 #define I82802AC       0x00ac
 #define PF38F4476      0x881c
+#define M28F00AP30     0x8963
 /* STMicroelectronics chips */
 #define M50LPW080       0x002F
 #define M50FLW080A     0x0080
@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct cfi_private *cfi,
                extp->MinorVersion = '1';
 }
 
+static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
+{
+       /*
+        * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
+        * Erase Supend for their small Erase Blocks(0x8000)
+        */
+       if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
+               return 1;
+       return 0;
+}
+
 static inline struct cfi_pri_intelext *
 read_pri_intelext(struct map_info *map, __u16 adr)
 {
@@ -831,21 +843,30 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
                     (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
                        goto sleep;
 
+               /* Do not allow suspend iff read/write to EB address */
+               if ((adr & chip->in_progress_block_mask) ==
+                   chip->in_progress_block_addr)
+                       goto sleep;
+
+               /* do not suspend small EBs, buggy Micron Chips */
+               if (cfi_is_micron_28F00AP30(cfi, chip) &&
+                   (chip->in_progress_block_mask == ~(0x8000-1)))
+                       goto sleep;
 
                /* Erase suspend */
-               map_write(map, CMD(0xB0), adr);
+               map_write(map, CMD(0xB0), chip->in_progress_block_addr);
 
                /* If the flash has finished erasing, then 'erase suspend'
                 * appears to make some (28F320) flash devices switch to
                 * 'read' mode.  Make sure that we switch to 'read status'
                 * mode so we get the right data. --rmk
                 */
-               map_write(map, CMD(0x70), adr);
+               map_write(map, CMD(0x70), chip->in_progress_block_addr);
                chip->oldstate = FL_ERASING;
                chip->state = FL_ERASE_SUSPENDING;
                chip->erase_suspended = 1;
                for (;;) {
-                       status = map_read(map, adr);
+                       status = map_read(map, chip->in_progress_block_addr);
                        if (map_word_andequal(map, status, status_OK, status_OK))
                                break;
 
@@ -1041,8 +1062,8 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                   sending the 0x70 (Read Status) command to an erasing
                   chip and expecting it to be ignored, that's what we
                   do. */
-               map_write(map, CMD(0xd0), adr);
-               map_write(map, CMD(0x70), adr);
+               map_write(map, CMD(0xd0), chip->in_progress_block_addr);
+               map_write(map, CMD(0x70), chip->in_progress_block_addr);
                chip->oldstate = FL_READY;
                chip->state = FL_ERASING;
                break;
@@ -1933,6 +1954,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        map_write(map, CMD(0xD0), adr);
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
+       chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(len - 1);
 
        ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
                                   adr, len,
index 668e2cbc155bbe008858ba9a11a5467fb5fc39ba..692902df259892a78e69964cf1069867d7336acc 100644 (file)
@@ -816,9 +816,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
                        goto sleep;
 
-               /* We could check to see if we're trying to access the sector
-                * that is currently being erased. However, no user will try
-                * anything like that so we just wait for the timeout. */
+               /* Do not allow suspend iff read/write to EB address */
+               if ((adr & chip->in_progress_block_mask) ==
+                   chip->in_progress_block_addr)
+                       goto sleep;
 
                /* Erase suspend */
                /* It's harmless to issue the Erase-Suspend and Erase-Resume
@@ -2267,6 +2268,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
        chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(map->size - 1);
 
        INVALIDATE_CACHE_UDELAY(map, chip,
                                adr, map->size,
@@ -2356,6 +2358,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
        chip->state = FL_ERASING;
        chip->erase_suspended = 0;
        chip->in_progress_block_addr = adr;
+       chip->in_progress_block_mask = ~(len - 1);
 
        INVALIDATE_CACHE_UDELAY(map, chip,
                                adr, len,
index d0cd6f8635d722ab3c1bcfcc32184f47c8dab24c..9c9f8936b63bc37bbcbd7c6d22d6ca85d69f388f 100644 (file)
@@ -162,7 +162,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
                ret = nanddev_erase(nand, &pos);
                if (ret) {
                        einfo->fail_addr = nanddev_pos_to_offs(nand, &pos);
-                       einfo->state = MTD_ERASE_FAILED;
 
                        return ret;
                }
@@ -170,8 +169,6 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
                nanddev_pos_next_eraseblock(nand, &pos);
        }
 
-       einfo->state = MTD_ERASE_DONE;
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(nanddev_mtd_erase);
index 10e953218948836e0151f022ef8745d8b523e574..1d779a35ac8ee03152f8d9b1a4f99df753995785 100644 (file)
@@ -2299,29 +2299,20 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc,
        /*
         * The legacy "num-cs" property indicates the number of CS on the only
         * chip connected to the controller (legacy bindings does not support
-        * more than one chip). CS are only incremented one by one while the RB
-        * pin is always the #0.
+        * more than one chip). The CS and RB pins are always the #0.
         *
         * When not using legacy bindings, a couple of "reg" and "nand-rb"
         * properties must be filled. For each chip, expressed as a subnode,
         * "reg" points to the CS lines and "nand-rb" to the RB line.
         */
-       if (pdata) {
+       if (pdata || nfc->caps->legacy_of_bindings) {
                nsels = 1;
-       } else if (nfc->caps->legacy_of_bindings &&
-                  !of_get_property(np, "num-cs", &nsels)) {
-               dev_err(dev, "missing num-cs property\n");
-               return -EINVAL;
-       } else if (!of_get_property(np, "reg", &nsels)) {
-               dev_err(dev, "missing reg property\n");
-               return -EINVAL;
-       }
-
-       if (!pdata)
-               nsels /= sizeof(u32);
-       if (!nsels) {
-               dev_err(dev, "invalid reg property size\n");
-               return -EINVAL;
+       } else {
+               nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32));
+               if (nsels <= 0) {
+                       dev_err(dev, "missing/invalid reg property\n");
+                       return -EINVAL;
+               }
        }
 
        /* Alloc the nand chip structure */
index f54518ffb36af43221bc01905a731d3c9e73d968..f2052fae21c7453ae6f5fa3698fd2d38fa1884ad 100644 (file)
@@ -645,7 +645,7 @@ static int tango_nand_probe(struct platform_device *pdev)
 
        writel_relaxed(MODE_RAW, nfc->pbus_base + PBUS_PAD_MODE);
 
-       clk = clk_get(&pdev->dev, NULL);
+       clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
index 4b8e9183489aa444edfa193d20fd004581470544..5872f31eaa60f91dae62bc1690e78aa97ca5c2a8 100644 (file)
@@ -501,7 +501,9 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
        void __iomem *reg_base = cqspi->iobase;
        void __iomem *ahb_base = cqspi->ahb_base;
        unsigned int remaining = n_rx;
+       unsigned int mod_bytes = n_rx % 4;
        unsigned int bytes_to_read = 0;
+       u8 *rxbuf_end = rxbuf + n_rx;
        int ret = 0;
 
        writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
@@ -530,11 +532,24 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
                }
 
                while (bytes_to_read != 0) {
+                       unsigned int word_remain = round_down(remaining, 4);
+
                        bytes_to_read *= cqspi->fifo_width;
                        bytes_to_read = bytes_to_read > remaining ?
                                        remaining : bytes_to_read;
-                       ioread32_rep(ahb_base, rxbuf,
-                                    DIV_ROUND_UP(bytes_to_read, 4));
+                       bytes_to_read = round_down(bytes_to_read, 4);
+                       /* Read 4 byte word chunks then single bytes */
+                       if (bytes_to_read) {
+                               ioread32_rep(ahb_base, rxbuf,
+                                            (bytes_to_read / 4));
+                       } else if (!word_remain && mod_bytes) {
+                               unsigned int temp = ioread32(ahb_base);
+
+                               bytes_to_read = mod_bytes;
+                               memcpy(rxbuf, &temp, min((unsigned int)
+                                                        (rxbuf_end - rxbuf),
+                                                        bytes_to_read));
+                       }
                        rxbuf += bytes_to_read;
                        remaining -= bytes_to_read;
                        bytes_to_read = cqspi_get_rd_sram_level(cqspi);
index 84aa9d6763753029f45c39483c9b84ca59299409..6da20b9688f7419aae4f806798eaa137c8c4f649 100644 (file)
@@ -942,7 +942,7 @@ int __init early_init_dt_scan_chosen_stdout(void)
        int offset;
        const char *p, *q, *options = NULL;
        int l;
-       const struct earlycon_id *match;
+       const struct earlycon_id **p_match;
        const void *fdt = initial_boot_params;
 
        offset = fdt_path_offset(fdt, "/chosen");
@@ -969,7 +969,10 @@ int __init early_init_dt_scan_chosen_stdout(void)
                return 0;
        }
 
-       for (match = __earlycon_table; match < __earlycon_table_end; match++) {
+       for (p_match = __earlycon_table; p_match < __earlycon_table_end;
+            p_match++) {
+               const struct earlycon_id *match = *p_match;
+
                if (!match->compatible[0])
                        continue;
 
index 304e891e35fcb060a8ff26f78122fa3c63a1eb87..60f2250fd96bec2cec1dd33f652edaac474d2182 100644 (file)
@@ -57,7 +57,7 @@ static void tm_to_opal(struct rtc_time *tm, u32 *y_m_d, u64 *h_m_s_ms)
 
 static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
        int retries = 10;
        u32 y_m_d;
        u64 h_m_s_ms;
@@ -66,13 +66,17 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (retries-- && (rc == OPAL_HARDWARE
-                                      || rc == OPAL_INTERNAL_ERROR))
-                       msleep(10);
-               else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
-                       break;
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        if (rc != OPAL_SUCCESS)
@@ -87,21 +91,26 @@ static int opal_get_rtc_time(struct device *dev, struct rtc_time *tm)
 
 static int opal_set_rtc_time(struct device *dev, struct rtc_time *tm)
 {
-       long rc = OPAL_BUSY;
+       s64 rc = OPAL_BUSY;
        int retries = 10;
        u32 y_m_d = 0;
        u64 h_m_s_ms = 0;
 
        tm_to_opal(tm, &y_m_d, &h_m_s_ms);
+
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
                rc = opal_rtc_write(y_m_d, h_m_s_ms);
-               if (rc == OPAL_BUSY_EVENT)
+               if (rc == OPAL_BUSY_EVENT) {
+                       msleep(OPAL_BUSY_DELAY_MS);
                        opal_poll_events(NULL);
-               else if (retries-- && (rc == OPAL_HARDWARE
-                                      || rc == OPAL_INTERNAL_ERROR))
-                       msleep(10);
-               else if (rc != OPAL_BUSY && rc != OPAL_BUSY_EVENT)
-                       break;
+               } else if (rc == OPAL_BUSY) {
+                       msleep(OPAL_BUSY_DELAY_MS);
+               } else if (rc == OPAL_HARDWARE || rc == OPAL_INTERNAL_ERROR) {
+                       if (retries--) {
+                               msleep(10); /* Wait 10ms before retry */
+                               rc = OPAL_BUSY; /* go around again */
+                       }
+               }
        }
 
        return rc == OPAL_SUCCESS ? 0 : -EIO;
index c44d7c7ffc920e9cfb35c521c6012cddfccb7b8a..1754f55e2facfb4b21169a7c97ee514392c9eaa8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
+ * the Free Software Foundation, either version 2 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
index 884419c37e8419c8e2a955e4406f75d68e1e1298..457ea1f8db309cb90ea2eef0feefe64be56e3f70 100644 (file)
@@ -183,7 +183,7 @@ static u16 slim_slicesize(int code)
                0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7
        };
 
-       clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
+       code = clamp(code, 1, (int)ARRAY_SIZE(sizetocode));
 
        return sizetocode[code - 1];
 }
index fe96a8b956fbd54424bea059af5b0be1240c91b3..f7ed1187518b9d2b47bedd29ae6b5a1e3ab566fd 100644 (file)
@@ -45,7 +45,7 @@ struct rpi_power_domains {
 struct rpi_power_domain_packet {
        u32 domain;
        u32 on;
-} __packet;
+};
 
 /*
  * Asks the firmware to enable or disable power on a specific power
index 6b5300ca44a67a8bcd75a5ad0149504220a2984e..885f5fcead777e7526f9c0e3b363bf9ca8584784 100644 (file)
@@ -1390,7 +1390,7 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif,
        }
 
        if (hif_drv->usr_conn_req.ies) {
-               conn_info.req_ies = kmemdup(conn_info.req_ies,
+               conn_info.req_ies = kmemdup(hif_drv->usr_conn_req.ies,
                                            hif_drv->usr_conn_req.ies_len,
                                            GFP_KERNEL);
                if (conn_info.req_ies)
index 3b3e1f6632d71c1aae24d690679b4b53673ce148..1dbe27c9946c16578a6ad0f82313c4adf797aef0 100644 (file)
@@ -121,6 +121,9 @@ struct gsm_dlci {
        struct mutex mutex;
 
        /* Link layer */
+       int mode;
+#define DLCI_MODE_ABM          0       /* Normal Asynchronous Balanced Mode */
+#define DLCI_MODE_ADM          1       /* Asynchronous Disconnected Mode */
        spinlock_t lock;        /* Protects the internal state */
        struct timer_list t1;   /* Retransmit timer for SABM and UA */
        int retries;
@@ -1364,7 +1367,13 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,
        ctrl->data = data;
        ctrl->len = clen;
        gsm->pending_cmd = ctrl;
-       gsm->cretries = gsm->n2;
+
+       /* If DLCI0 is in ADM mode skip retries, it won't respond */
+       if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
+               gsm->cretries = 1;
+       else
+               gsm->cretries = gsm->n2;
+
        mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
        gsm_control_transmit(gsm, ctrl);
        spin_unlock_irqrestore(&gsm->control_lock, flags);
@@ -1472,6 +1481,7 @@ static void gsm_dlci_t1(struct timer_list *t)
                        if (debug & 8)
                                pr_info("DLCI %d opening in ADM mode.\n",
                                        dlci->addr);
+                       dlci->mode = DLCI_MODE_ADM;
                        gsm_dlci_open(dlci);
                } else {
                        gsm_dlci_close(dlci);
@@ -2861,11 +2871,22 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
 static int gsm_carrier_raised(struct tty_port *port)
 {
        struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
+       struct gsm_mux *gsm = dlci->gsm;
+
        /* Not yet open so no carrier info */
        if (dlci->state != DLCI_OPEN)
                return 0;
        if (debug & 2)
                return 1;
+
+       /*
+        * Basic mode with control channel in ADM mode may not respond
+        * to CMD_MSC at all and modem_rx is empty.
+        */
+       if (gsm->encoding == 0 && gsm->dlci[0]->mode == DLCI_MODE_ADM &&
+           !dlci->modem_rx)
+               return 1;
+
        return dlci->modem_rx & TIOCM_CD;
 }
 
index a24278380fec2a6a67b2513514f08ecd6688dfe2..22683393a0f2c3f7b6054d367823a3f99f4df103 100644 (file)
@@ -169,7 +169,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
  */
 int __init setup_earlycon(char *buf)
 {
-       const struct earlycon_id *match;
+       const struct earlycon_id **p_match;
 
        if (!buf || !buf[0])
                return -EINVAL;
@@ -177,7 +177,9 @@ int __init setup_earlycon(char *buf)
        if (early_con.flags & CON_ENABLED)
                return -EALREADY;
 
-       for (match = __earlycon_table; match < __earlycon_table_end; match++) {
+       for (p_match = __earlycon_table; p_match < __earlycon_table_end;
+            p_match++) {
+               const struct earlycon_id *match = *p_match;
                size_t len = strlen(match->name);
 
                if (strncmp(buf, match->name, len))
index 91f3a1a5cb7fa81ac82a2289e792fc5c908df9b2..c2fc6bef7a6f28a6fc3fe9f18782c555bdb35a35 100644 (file)
@@ -316,7 +316,7 @@ static u32 imx_uart_readl(struct imx_port *sport, u32 offset)
                 * differ from the value that was last written. As it only
                 * clears after being set, reread conditionally.
                 */
-               if (sport->ucr2 & UCR2_SRST)
+               if (!(sport->ucr2 & UCR2_SRST))
                        sport->ucr2 = readl(sport->port.membase + offset);
                return sport->ucr2;
                break;
@@ -1833,6 +1833,11 @@ static int imx_uart_rs485_config(struct uart_port *port,
                rs485conf->flags &= ~SER_RS485_ENABLED;
 
        if (rs485conf->flags & SER_RS485_ENABLED) {
+               /* Enable receiver if low-active RTS signal is requested */
+               if (sport->have_rtscts &&  !sport->have_rtsgpio &&
+                   !(rs485conf->flags & SER_RS485_RTS_ON_SEND))
+                       rs485conf->flags |= SER_RS485_RX_DURING_TX;
+
                /* disable transmitter */
                ucr2 = imx_uart_readl(sport, UCR2);
                if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
@@ -2265,6 +2270,18 @@ static int imx_uart_probe(struct platform_device *pdev)
            (!sport->have_rtscts && !sport->have_rtsgpio))
                dev_err(&pdev->dev, "no RTS control, disabling rs485\n");
 
+       /*
+        * If using the i.MX UART RTS/CTS control then the RTS (CTS_B)
+        * signal cannot be set low during transmission in case the
+        * receiver is off (limitation of the i.MX UART IP).
+        */
+       if (sport->port.rs485.flags & SER_RS485_ENABLED &&
+           sport->have_rtscts && !sport->have_rtsgpio &&
+           (!(sport->port.rs485.flags & SER_RS485_RTS_ON_SEND) &&
+            !(sport->port.rs485.flags & SER_RS485_RX_DURING_TX)))
+               dev_err(&pdev->dev,
+                       "low-active RTS not possible when receiver is off, enabling receiver\n");
+
        imx_uart_rs485_config(&sport->port, &sport->port.rs485);
 
        /* Disable interrupts before requesting them */
index 750e5645dc857c7ba63bd0a848e9f6055fac988c..f503fab1e2685f2451d540ed18d5f474a71581b4 100644 (file)
@@ -495,7 +495,6 @@ static void mvebu_uart_set_termios(struct uart_port *port,
                termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
                termios->c_cflag &= CREAD | CBAUD;
                termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
-               termios->c_lflag = old->c_lflag;
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
index 65ff669373d4a0325ffd97a04f070ee3e389217a..a1b3eb04cb32c78f17ccd32698ced4a459091869 100644 (file)
@@ -1022,6 +1022,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
        struct qcom_geni_serial_port *port;
        struct uart_port *uport;
        struct resource *res;
+       int irq;
 
        if (pdev->dev.of_node)
                line = of_alias_get_id(pdev->dev.of_node, "serial");
@@ -1061,11 +1062,12 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
        port->rx_fifo_depth = DEF_FIFO_DEPTH_WORDS;
        port->tx_fifo_width = DEF_FIFO_WIDTH_BITS;
 
-       uport->irq = platform_get_irq(pdev, 0);
-       if (uport->irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ %d\n", uport->irq);
-               return uport->irq;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "Failed to get IRQ %d\n", irq);
+               return irq;
        }
+       uport->irq = irq;
 
        uport->private_data = &qcom_geni_console_driver;
        platform_set_drvdata(pdev, port);
index abcb4d09a2d866d05b7af3c1ff5d3f68492514c1..bd72dd843338dc9a3aecaacaa04dc7b2fc2442db 100644 (file)
@@ -1181,7 +1181,7 @@ static int __init cdns_early_console_setup(struct earlycon_device *device,
        /* only set baud if specified on command line - otherwise
         * assume it has been initialized by a boot loader.
         */
-       if (device->baud) {
+       if (port->uartclk && device->baud) {
                u32 cd = 0, bdiv = 0;
                u32 mr;
                int div8;
index 63114ea35ec1b8f3620ec888155b929ed1915200..7c838b90a31d636865ce99a84466967d57b777aa 100644 (file)
@@ -2816,7 +2816,10 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
 
        kref_init(&tty->kref);
        tty->magic = TTY_MAGIC;
-       tty_ldisc_init(tty);
+       if (tty_ldisc_init(tty)) {
+               kfree(tty);
+               return NULL;
+       }
        tty->session = NULL;
        tty->pgrp = NULL;
        mutex_init(&tty->legacy_mutex);
index 050f4d650891763f96800244869821afb9d1586e..fb7329ab2b37a85f0682805d2fe996f6279df64b 100644 (file)
@@ -176,12 +176,11 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
                        return ERR_CAST(ldops);
        }
 
-       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
-       if (ld == NULL) {
-               put_ldops(ldops);
-               return ERR_PTR(-ENOMEM);
-       }
-
+       /*
+        * There is no way to handle allocation failure of only 16 bytes.
+        * Let's simplify error handling and save more memory.
+        */
+       ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
        ld->ops = ldops;
        ld->tty = tty;
 
@@ -527,19 +526,16 @@ static int tty_ldisc_failto(struct tty_struct *tty, int ld)
 static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
 {
        /* There is an outstanding reference here so this is safe */
-       old = tty_ldisc_get(tty, old->ops->num);
-       WARN_ON(IS_ERR(old));
-       tty->ldisc = old;
-       tty_set_termios_ldisc(tty, old->ops->num);
-       if (tty_ldisc_open(tty, old) < 0) {
-               tty_ldisc_put(old);
+       if (tty_ldisc_failto(tty, old->ops->num) < 0) {
+               const char *name = tty_name(tty);
+
+               pr_warn("Falling back ldisc for %s.\n", name);
                /* The traditional behaviour is to fall back to N_TTY, we
                   want to avoid falling back to N_NULL unless we have no
                   choice to avoid the risk of breaking anything */
                if (tty_ldisc_failto(tty, N_TTY) < 0 &&
                    tty_ldisc_failto(tty, N_NULL) < 0)
-                       panic("Couldn't open N_NULL ldisc for %s.",
-                             tty_name(tty));
+                       panic("Couldn't open N_NULL ldisc for %s.", name);
        }
 }
 
@@ -824,12 +820,13 @@ EXPORT_SYMBOL_GPL(tty_ldisc_release);
  *     the tty structure is not completely set up when this call is made.
  */
 
-void tty_ldisc_init(struct tty_struct *tty)
+int tty_ldisc_init(struct tty_struct *tty)
 {
        struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
        if (IS_ERR(ld))
-               panic("n_tty: init_tty");
+               return PTR_ERR(ld);
        tty->ldisc = ld;
+       return 0;
 }
 
 /**
index f695a7e8c314585c8b0df8ab88f44d897986839b..c690d100adcd075b2999b82443b08e4ce03c2b53 100644 (file)
@@ -19,7 +19,7 @@
  * # echo -n "ed963694-e847-4b2a-85af-bc9cfc11d6f3" \
  *    > /sys/bus/vmbus/drivers/uio_hv_generic/bind
  */
-
+#define DEBUG 1
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/device.h>
@@ -94,10 +94,11 @@ hv_uio_irqcontrol(struct uio_info *info, s32 irq_state)
  */
 static void hv_uio_channel_cb(void *context)
 {
-       struct hv_uio_private_data *pdata = context;
-       struct hv_device *dev = pdata->device;
+       struct vmbus_channel *chan = context;
+       struct hv_device *hv_dev = chan->device_obj;
+       struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
 
-       dev->channel->inbound.ring_buffer->interrupt_mask = 1;
+       chan->inbound.ring_buffer->interrupt_mask = 1;
        virt_mb();
 
        uio_event_notify(&pdata->info);
@@ -121,78 +122,46 @@ static void hv_uio_rescind(struct vmbus_channel *channel)
        uio_event_notify(&pdata->info);
 }
 
-/*
- * Handle fault when looking for sub channel ring buffer
- * Subchannel ring buffer is same as resource 0 which is main ring buffer
- * This is derived from uio_vma_fault
+/* Sysfs API to allow mmap of the ring buffers
+ * The ring buffer is allocated as contiguous memory by vmbus_open
  */
-static int hv_uio_vma_fault(struct vm_fault *vmf)
-{
-       struct vm_area_struct *vma = vmf->vma;
-       void *ring_buffer = vma->vm_private_data;
-       struct page *page;
-       void *addr;
-
-       addr = ring_buffer + (vmf->pgoff << PAGE_SHIFT);
-       page = virt_to_page(addr);
-       get_page(page);
-       vmf->page = page;
-       return 0;
-}
-
-static const struct vm_operations_struct hv_uio_vm_ops = {
-       .fault = hv_uio_vma_fault,
-};
-
-/* Sysfs API to allow mmap of the ring buffers */
 static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
                            struct bin_attribute *attr,
                            struct vm_area_struct *vma)
 {
        struct vmbus_channel *channel
                = container_of(kobj, struct vmbus_channel, kobj);
-       unsigned long requested_pages, actual_pages;
-
-       if (vma->vm_end < vma->vm_start)
-               return -EINVAL;
-
-       /* only allow 0 for now */
-       if (vma->vm_pgoff > 0)
-               return -EINVAL;
+       struct hv_device *dev = channel->primary_channel->device_obj;
+       u16 q_idx = channel->offermsg.offer.sub_channel_index;
 
-       requested_pages = vma_pages(vma);
-       actual_pages = 2 * HV_RING_SIZE;
-       if (requested_pages > actual_pages)
-               return -EINVAL;
+       dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n",
+               q_idx, vma_pages(vma), vma->vm_pgoff);
 
-       vma->vm_private_data = channel->ringbuffer_pages;
-       vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
-       vma->vm_ops = &hv_uio_vm_ops;
-       return 0;
+       return vm_iomap_memory(vma, virt_to_phys(channel->ringbuffer_pages),
+                              channel->ringbuffer_pagecount << PAGE_SHIFT);
 }
 
-static struct bin_attribute ring_buffer_bin_attr __ro_after_init = {
+static const struct bin_attribute ring_buffer_bin_attr = {
        .attr = {
                .name = "ring",
                .mode = 0600,
-               /* size is set at init time */
        },
+       .size = 2 * HV_RING_SIZE * PAGE_SIZE,
        .mmap = hv_uio_ring_mmap,
 };
 
-/* Callback from VMBUS subystem when new channel created. */
+/* Callback from VMBUS subsystem when new channel created. */
 static void
 hv_uio_new_channel(struct vmbus_channel *new_sc)
 {
        struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
        struct device *device = &hv_dev->device;
-       struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
        const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
        int ret;
 
        /* Create host communication ring */
        ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0,
-                        hv_uio_channel_cb, pdata);
+                        hv_uio_channel_cb, new_sc);
        if (ret) {
                dev_err(device, "vmbus_open subchannel failed: %d\n", ret);
                return;
@@ -234,7 +203,7 @@ hv_uio_probe(struct hv_device *dev,
 
        ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE,
                         HV_RING_SIZE * PAGE_SIZE, NULL, 0,
-                        hv_uio_channel_cb, pdata);
+                        hv_uio_channel_cb, dev->channel);
        if (ret)
                goto fail;
 
@@ -326,6 +295,11 @@ hv_uio_probe(struct hv_device *dev,
        vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind);
        vmbus_set_sc_create_callback(dev->channel, hv_uio_new_channel);
 
+       ret = sysfs_create_bin_file(&dev->channel->kobj, &ring_buffer_bin_attr);
+       if (ret)
+               dev_notice(&dev->device,
+                          "sysfs create ring bin file failed; %d\n", ret);
+
        hv_set_drvdata(dev, pdata);
 
        return 0;
index 75f7fb151f713b737a5d9a3a5b07a77de68bdf25..987fc5ba63211bb5829a8f38629e86ab6022a094 100644 (file)
@@ -207,5 +207,6 @@ config USB_ULPI_BUS
 
 config USB_ROLE_SWITCH
        tristate
+       select USB_COMMON
 
 endif # USB_SUPPORT
index 777036ae63674af94e845a78e0cf75e607f8ba68..0a42c5df3c0fb3971c538689697dd52644f443dd 100644 (file)
@@ -2262,7 +2262,8 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
                hcd->state = HC_STATE_SUSPENDED;
 
                if (!PMSG_IS_AUTO(msg))
-                       usb_phy_roothub_power_off(hcd->phy_roothub);
+                       usb_phy_roothub_suspend(hcd->self.sysdev,
+                                               hcd->phy_roothub);
 
                /* Did we race with a root-hub wakeup event? */
                if (rhdev->do_remote_wakeup) {
@@ -2302,7 +2303,8 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
        }
 
        if (!PMSG_IS_AUTO(msg)) {
-               status = usb_phy_roothub_power_on(hcd->phy_roothub);
+               status = usb_phy_roothub_resume(hcd->self.sysdev,
+                                               hcd->phy_roothub);
                if (status)
                        return status;
        }
@@ -2344,7 +2346,7 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg)
                }
        } else {
                hcd->state = old_state;
-               usb_phy_roothub_power_off(hcd->phy_roothub);
+               usb_phy_roothub_suspend(hcd->self.sysdev, hcd->phy_roothub);
                dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
                                "resume", status);
                if (status != -ESHUTDOWN)
@@ -2377,6 +2379,7 @@ void usb_hcd_resume_root_hub (struct usb_hcd *hcd)
 
        spin_lock_irqsave (&hcd_root_hub_lock, flags);
        if (hcd->rh_registered) {
+               pm_wakeup_event(&hcd->self.root_hub->dev, 0);
                set_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags);
                queue_work(pm_wq, &hcd->wakeup_work);
        }
@@ -2758,12 +2761,16 @@ int usb_add_hcd(struct usb_hcd *hcd,
        }
 
        if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
-               hcd->phy_roothub = usb_phy_roothub_init(hcd->self.sysdev);
+               hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
                if (IS_ERR(hcd->phy_roothub)) {
                        retval = PTR_ERR(hcd->phy_roothub);
-                       goto err_phy_roothub_init;
+                       goto err_phy_roothub_alloc;
                }
 
+               retval = usb_phy_roothub_init(hcd->phy_roothub);
+               if (retval)
+                       goto err_phy_roothub_alloc;
+
                retval = usb_phy_roothub_power_on(hcd->phy_roothub);
                if (retval)
                        goto err_usb_phy_roothub_power_on;
@@ -2936,7 +2943,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
        usb_phy_roothub_power_off(hcd->phy_roothub);
 err_usb_phy_roothub_power_on:
        usb_phy_roothub_exit(hcd->phy_roothub);
-err_phy_roothub_init:
+err_phy_roothub_alloc:
        if (hcd->remove_phy && hcd->usb_phy) {
                usb_phy_shutdown(hcd->usb_phy);
                usb_put_phy(hcd->usb_phy);
index f6ea16e9f6bb975a09e296f2493a5a687828d920..aa9968d90a48c301e6af566d00a20139397e1742 100644 (file)
@@ -653,12 +653,17 @@ void usb_wakeup_notification(struct usb_device *hdev,
                unsigned int portnum)
 {
        struct usb_hub *hub;
+       struct usb_port *port_dev;
 
        if (!hdev)
                return;
 
        hub = usb_hub_to_struct_hub(hdev);
        if (hub) {
+               port_dev = hub->ports[portnum - 1];
+               if (port_dev && port_dev->child)
+                       pm_wakeup_event(&port_dev->child->dev, 0);
+
                set_bit(portnum, hub->wakeup_bits);
                kick_hub_wq(hub);
        }
@@ -3434,8 +3439,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
 
        /* Skip the initial Clear-Suspend step for a remote wakeup */
        status = hub_port_status(hub, port1, &portstatus, &portchange);
-       if (status == 0 && !port_is_suspended(hub, portstatus))
+       if (status == 0 && !port_is_suspended(hub, portstatus)) {
+               if (portchange & USB_PORT_STAT_C_SUSPEND)
+                       pm_wakeup_event(&udev->dev, 0);
                goto SuspendCleared;
+       }
 
        /* see 7.1.7.7; affects power usage, but not budgeting */
        if (hub_is_superspeed(hub->hdev))
index 09b7c43c0ea4c69e365f22274bb8c36a984d49d2..9879767452a23e6a0c1ceeea65cfc0b8874fa65a 100644 (file)
@@ -19,19 +19,6 @@ struct usb_phy_roothub {
        struct list_head        list;
 };
 
-static struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
-{
-       struct usb_phy_roothub *roothub_entry;
-
-       roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
-       if (!roothub_entry)
-               return ERR_PTR(-ENOMEM);
-
-       INIT_LIST_HEAD(&roothub_entry->list);
-
-       return roothub_entry;
-}
-
 static int usb_phy_roothub_add_phy(struct device *dev, int index,
                                   struct list_head *list)
 {
@@ -45,9 +32,11 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
                        return PTR_ERR(phy);
        }
 
-       roothub_entry = usb_phy_roothub_alloc(dev);
-       if (IS_ERR(roothub_entry))
-               return PTR_ERR(roothub_entry);
+       roothub_entry = devm_kzalloc(dev, sizeof(*roothub_entry), GFP_KERNEL);
+       if (!roothub_entry)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&roothub_entry->list);
 
        roothub_entry->phy = phy;
 
@@ -56,28 +45,44 @@ static int usb_phy_roothub_add_phy(struct device *dev, int index,
        return 0;
 }
 
-struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
+struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev)
 {
        struct usb_phy_roothub *phy_roothub;
-       struct usb_phy_roothub *roothub_entry;
-       struct list_head *head;
        int i, num_phys, err;
 
+       if (!IS_ENABLED(CONFIG_GENERIC_PHY))
+               return NULL;
+
        num_phys = of_count_phandle_with_args(dev->of_node, "phys",
                                              "#phy-cells");
        if (num_phys <= 0)
                return NULL;
 
-       phy_roothub = usb_phy_roothub_alloc(dev);
-       if (IS_ERR(phy_roothub))
-               return phy_roothub;
+       phy_roothub = devm_kzalloc(dev, sizeof(*phy_roothub), GFP_KERNEL);
+       if (!phy_roothub)
+               return ERR_PTR(-ENOMEM);
+
+       INIT_LIST_HEAD(&phy_roothub->list);
 
        for (i = 0; i < num_phys; i++) {
                err = usb_phy_roothub_add_phy(dev, i, &phy_roothub->list);
                if (err)
-                       goto err_out;
+                       return ERR_PTR(err);
        }
 
+       return phy_roothub;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc);
+
+int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub)
+{
+       struct usb_phy_roothub *roothub_entry;
+       struct list_head *head;
+       int err;
+
+       if (!phy_roothub)
+               return 0;
+
        head = &phy_roothub->list;
 
        list_for_each_entry(roothub_entry, head, list) {
@@ -86,14 +91,13 @@ struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev)
                        goto err_exit_phys;
        }
 
-       return phy_roothub;
+       return 0;
 
 err_exit_phys:
        list_for_each_entry_continue_reverse(roothub_entry, head, list)
                phy_exit(roothub_entry->phy);
 
-err_out:
-       return ERR_PTR(err);
+       return err;
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_init);
 
@@ -111,7 +115,7 @@ int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub)
        list_for_each_entry(roothub_entry, head, list) {
                err = phy_exit(roothub_entry->phy);
                if (err)
-                       ret = ret;
+                       ret = err;
        }
 
        return ret;
@@ -156,3 +160,38 @@ void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub)
                phy_power_off(roothub_entry->phy);
 }
 EXPORT_SYMBOL_GPL(usb_phy_roothub_power_off);
+
+int usb_phy_roothub_suspend(struct device *controller_dev,
+                           struct usb_phy_roothub *phy_roothub)
+{
+       usb_phy_roothub_power_off(phy_roothub);
+
+       /* keep the PHYs initialized so the device can wake up the system */
+       if (device_may_wakeup(controller_dev))
+               return 0;
+
+       return usb_phy_roothub_exit(phy_roothub);
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_suspend);
+
+int usb_phy_roothub_resume(struct device *controller_dev,
+                          struct usb_phy_roothub *phy_roothub)
+{
+       int err;
+
+       /* if the device can't wake up the system _exit was called */
+       if (!device_may_wakeup(controller_dev)) {
+               err = usb_phy_roothub_init(phy_roothub);
+               if (err)
+                       return err;
+       }
+
+       err = usb_phy_roothub_power_on(phy_roothub);
+
+       /* undo _init if _power_on failed */
+       if (err && !device_may_wakeup(controller_dev))
+               usb_phy_roothub_exit(phy_roothub);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(usb_phy_roothub_resume);
index 6fde59bfbff8ace58bebb50bc88348eab03a1ca2..88a3c037e9df59194ba94d3ecd7ec3e2626ccb33 100644 (file)
@@ -1,7 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * USB roothub wrapper
+ *
+ * Copyright (C) 2018 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ */
+
+#ifndef __USB_CORE_PHY_H_
+#define __USB_CORE_PHY_H_
+
+struct device;
 struct usb_phy_roothub;
 
-struct usb_phy_roothub *usb_phy_roothub_init(struct device *dev);
+struct usb_phy_roothub *usb_phy_roothub_alloc(struct device *dev);
+
+int usb_phy_roothub_init(struct usb_phy_roothub *phy_roothub);
 int usb_phy_roothub_exit(struct usb_phy_roothub *phy_roothub);
 
 int usb_phy_roothub_power_on(struct usb_phy_roothub *phy_roothub);
 void usb_phy_roothub_power_off(struct usb_phy_roothub *phy_roothub);
+
+int usb_phy_roothub_suspend(struct device *controller_dev,
+                           struct usb_phy_roothub *phy_roothub);
+int usb_phy_roothub_resume(struct device *controller_dev,
+                          struct usb_phy_roothub *phy_roothub);
+
+#endif /* __USB_CORE_PHY_H_ */
index 920f48a49a87021a513b4e395a903044a558abf5..c55def2f1320f92c6c0c652fc94c7056165ee467 100644 (file)
@@ -186,6 +186,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x03f0, 0x0701), .driver_info =
                        USB_QUIRK_STRING_FETCH_255 },
 
+       /* HP v222w 16GB Mini USB Drive */
+       { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT },
+
        /* Creative SB Audigy 2 NX */
        { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
 
index 48779c44c361d98db9f25ce3609860d243beea9f..eb494ec547e806e9d5656f072160d58bf68a0d17 100644 (file)
@@ -320,9 +320,11 @@ int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci)
 
 void xhci_dbc_tty_unregister_driver(void)
 {
-       tty_unregister_driver(dbc_tty_driver);
-       put_tty_driver(dbc_tty_driver);
-       dbc_tty_driver = NULL;
+       if (dbc_tty_driver) {
+               tty_unregister_driver(dbc_tty_driver);
+               put_tty_driver(dbc_tty_driver);
+               dbc_tty_driver = NULL;
+       }
 }
 
 static void dbc_rx_push(unsigned long _port)
index f17b7eab66cf9e51edec5b573a60ac909f6dc0b3..85ffda85f8ab39043c5323a3799420d14c98baa8 100644 (file)
@@ -126,7 +126,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info())
                xhci->quirks |= XHCI_AMD_PLL_FIX;
 
-       if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x43bb)
+       if (pdev->vendor == PCI_VENDOR_ID_AMD &&
+               (pdev->device == 0x15e0 ||
+                pdev->device == 0x15e1 ||
+                pdev->device == 0x43bb))
                xhci->quirks |= XHCI_SUSPEND_DELAY;
 
        if (pdev->vendor == PCI_VENDOR_ID_AMD)
index df327dcc2bac3b934399360ed32b504c7fbeabc1..c1b22fc64e387a3bf7f836729de1ddcd2676d8fc 100644 (file)
@@ -157,6 +157,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
        struct resource         *res;
        struct usb_hcd          *hcd;
        struct clk              *clk;
+       struct clk              *reg_clk;
        int                     ret;
        int                     irq;
 
@@ -226,17 +227,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
        hcd->rsrc_len = resource_size(res);
 
        /*
-        * Not all platforms have a clk so it is not an error if the
-        * clock does not exists.
+        * Not all platforms have clks so it is not an error if the
+        * clock do not exist.
         */
+       reg_clk = devm_clk_get(&pdev->dev, "reg");
+       if (!IS_ERR(reg_clk)) {
+               ret = clk_prepare_enable(reg_clk);
+               if (ret)
+                       goto put_hcd;
+       } else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
+               ret = -EPROBE_DEFER;
+               goto put_hcd;
+       }
+
        clk = devm_clk_get(&pdev->dev, NULL);
        if (!IS_ERR(clk)) {
                ret = clk_prepare_enable(clk);
                if (ret)
-                       goto put_hcd;
+                       goto disable_reg_clk;
        } else if (PTR_ERR(clk) == -EPROBE_DEFER) {
                ret = -EPROBE_DEFER;
-               goto put_hcd;
+               goto disable_reg_clk;
        }
 
        xhci = hcd_to_xhci(hcd);
@@ -252,6 +263,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
        device_wakeup_enable(hcd->self.controller);
 
        xhci->clk = clk;
+       xhci->reg_clk = reg_clk;
        xhci->main_hcd = hcd;
        xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
                        dev_name(&pdev->dev), hcd);
@@ -320,8 +332,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
        usb_put_hcd(xhci->shared_hcd);
 
 disable_clk:
-       if (!IS_ERR(clk))
-               clk_disable_unprepare(clk);
+       clk_disable_unprepare(clk);
+
+disable_reg_clk:
+       clk_disable_unprepare(reg_clk);
 
 put_hcd:
        usb_put_hcd(hcd);
@@ -338,6 +352,7 @@ static int xhci_plat_remove(struct platform_device *dev)
        struct usb_hcd  *hcd = platform_get_drvdata(dev);
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        struct clk *clk = xhci->clk;
+       struct clk *reg_clk = xhci->reg_clk;
 
        xhci->xhc_state |= XHCI_STATE_REMOVING;
 
@@ -347,8 +362,8 @@ static int xhci_plat_remove(struct platform_device *dev)
        usb_remove_hcd(hcd);
        usb_put_hcd(xhci->shared_hcd);
 
-       if (!IS_ERR(clk))
-               clk_disable_unprepare(clk);
+       clk_disable_unprepare(clk);
+       clk_disable_unprepare(reg_clk);
        usb_put_hcd(hcd);
 
        pm_runtime_set_suspended(&dev->dev);
@@ -420,7 +435,6 @@ MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
 static struct platform_driver usb_xhci_driver = {
        .probe  = xhci_plat_probe,
        .remove = xhci_plat_remove,
-       .shutdown       = usb_hcd_platform_shutdown,
        .driver = {
                .name = "xhci-hcd",
                .pm = &xhci_plat_pm_ops,
index 05c909b04f14c544c0ac7a8fba3a8c1bdd3a41f2..6dfc4867dbcf23ec34cecfd0658f93dae242500d 100644 (file)
@@ -1729,8 +1729,9 @@ struct xhci_hcd {
        int             page_shift;
        /* msi-x vectors */
        int             msix_count;
-       /* optional clock */
+       /* optional clocks */
        struct clk              *clk;
+       struct clk              *reg_clk;
        /* data structures */
        struct xhci_device_context_array *dcbaa;
        struct xhci_ring        *cmd_ring;
index 05a679d5e3a2b5487a852330edafd58ccba60b32..6a60bc0490c5270e8434e4d94e36e4120db215f6 100644 (file)
@@ -451,7 +451,6 @@ static int dsps_musb_init(struct musb *musb)
        if (!rev)
                return -ENODEV;
 
-       usb_phy_init(musb->xceiv);
        if (IS_ERR(musb->phy))  {
                musb->phy = NULL;
        } else {
@@ -501,7 +500,6 @@ static int dsps_musb_exit(struct musb *musb)
        struct dsps_glue *glue = dev_get_drvdata(dev->parent);
 
        del_timer_sync(&musb->dev_timer);
-       usb_phy_shutdown(musb->xceiv);
        phy_power_off(musb->phy);
        phy_exit(musb->phy);
        debugfs_remove_recursive(glue->dbgfs_root);
index 3a8451a15f7f735acb90886a1ee3521ebbb7b39f..4fa372c845e1529e600d0d8408de7fc3627671b3 100644 (file)
@@ -2754,6 +2754,7 @@ int musb_host_setup(struct musb *musb, int power_budget)
        hcd->self.otg_port = 1;
        musb->xceiv->otg->host = &hcd->self;
        hcd->power_budget = 2 * (power_budget ? : 250);
+       hcd->skip_phy_initialization = 1;
 
        ret = usb_add_hcd(hcd, 0, 0);
        if (ret < 0)
index a646820f5a78f0ae67551ff0b55b1b7e13c5f797..533f127c30ad846f236170f36a61a127ea9db6ab 100644 (file)
@@ -62,6 +62,7 @@ config USB_SERIAL_SIMPLE
                - Fundamental Software dongle.
                - Google USB serial devices
                - HP4x calculators
+               - Libtransistor USB console
                - a number of Motorola phones
                - Motorola Tetra devices
                - Novatel Wireless GPS receivers
index de1e759dd51220880ca364f9e1920af360f5e88d..eb6c26cbe5792b0e535c77b9e2e245b700071458 100644 (file)
@@ -214,6 +214,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
        { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
        { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
+       { USB_DEVICE(0x3923, 0x7A0B) }, /* National Instruments USB Serial Console */
        { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
        { } /* Terminating Entry */
 };
index 87202ad5a50dfb4d8afe865ce57a7b5fbe0d6b8b..7ea221d42dbadbbef33bb1e02ae35775d5765d62 100644 (file)
@@ -1898,7 +1898,8 @@ static int ftdi_8u2232c_probe(struct usb_serial *serial)
                return ftdi_jtag_probe(serial);
 
        if (udev->product &&
-               (!strcmp(udev->product, "BeagleBone/XDS100V2") ||
+               (!strcmp(udev->product, "Arrow USB Blaster") ||
+                !strcmp(udev->product, "BeagleBone/XDS100V2") ||
                 !strcmp(udev->product, "SNAP Connect E10")))
                return ftdi_jtag_probe(serial);
 
index 4ef79e29cb26031f4ccf100e34de453d41c031d4..40864c2bd9dc0ad73e8c5dd0701f621c4302712c 100644 (file)
@@ -63,6 +63,11 @@ DEVICE(flashloader, FLASHLOADER_IDS);
                                        0x01) }
 DEVICE(google, GOOGLE_IDS);
 
+/* Libtransistor USB console */
+#define LIBTRANSISTOR_IDS()                    \
+       { USB_DEVICE(0x1209, 0x8b00) }
+DEVICE(libtransistor, LIBTRANSISTOR_IDS);
+
 /* ViVOpay USB Serial Driver */
 #define VIVOPAY_IDS()                  \
        { USB_DEVICE(0x1d5f, 0x1004) }  /* ViVOpay 8800 */
@@ -110,6 +115,7 @@ static struct usb_serial_driver * const serial_drivers[] = {
        &funsoft_device,
        &flashloader_device,
        &google_device,
+       &libtransistor_device,
        &vivopay_device,
        &moto_modem_device,
        &motorola_tetra_device,
@@ -126,6 +132,7 @@ static const struct usb_device_id id_table[] = {
        FUNSOFT_IDS(),
        FLASHLOADER_IDS(),
        GOOGLE_IDS(),
+       LIBTRANSISTOR_IDS(),
        VIVOPAY_IDS(),
        MOTO_IDS(),
        MOTOROLA_TETRA_IDS(),
index b57891c1fd31a7e70b14ada774f824d30b36196e..7afbea5122077b3dd0cbe217ad7c839837f499b4 100644 (file)
@@ -5,6 +5,6 @@ obj-$(CONFIG_TYPEC_UCSI)        += typec_ucsi.o
 
 typec_ucsi-y                   := ucsi.o
 
-typec_ucsi-$(CONFIG_FTRACE)    += trace.o
+typec_ucsi-$(CONFIG_TRACING)   += trace.o
 
 obj-$(CONFIG_UCSI_ACPI)                += ucsi_acpi.o
index bf0977fbd100a72b2384d52a91c114dbbf694813..bd5cca5632b395def6384ec233d8ba5926e81c93 100644 (file)
@@ -28,7 +28,7 @@
  * difficult to estimate the time it takes for the system to process the command
  * before it is actually passed to the PPM.
  */
-#define UCSI_TIMEOUT_MS                1000
+#define UCSI_TIMEOUT_MS                5000
 
 /*
  * UCSI_SWAP_TIMEOUT_MS - Timeout for role swap requests
index c31c8402a0c55ddd2f4b463ebabd28be6438f490..d41d0cdeec0f2a1861d8d42385a9719789cab558 100644 (file)
@@ -186,7 +186,12 @@ static ssize_t rebind_store(struct device_driver *dev, const char *buf,
        if (!bid)
                return -ENODEV;
 
+       /* device_attach() callers should hold parent lock for USB */
+       if (bid->udev->dev.parent)
+               device_lock(bid->udev->dev.parent);
        ret = device_attach(&bid->udev->dev);
+       if (bid->udev->dev.parent)
+               device_unlock(bid->udev->dev.parent);
        if (ret < 0) {
                dev_err(&bid->udev->dev, "rebind failed\n");
                return ret;
index 473fb8a872893caa3494fe9a4a85b60600bdfd28..bf8afe9b5883850325fb70fc3873bff20237040b 100644 (file)
@@ -243,7 +243,7 @@ enum usbip_side {
 #define        VUDC_EVENT_ERROR_USB    (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 #define        VUDC_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
 
-#define        VDEV_EVENT_REMOVED      (USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
+#define        VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
 #define        VDEV_EVENT_DOWN         (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define        VDEV_EVENT_ERROR_TCP    (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define        VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
index 5b4c0864ad92ae6ac40e19b5b10f30667bc09207..5d88917c963149b0ba1daa02cc4da4e84ca3c106 100644 (file)
@@ -91,10 +91,6 @@ static void event_handler(struct work_struct *work)
                        unset_event(ud, USBIP_EH_UNUSABLE);
                }
 
-               /* Stop the error handler. */
-               if (ud->event & USBIP_EH_BYE)
-                       usbip_dbg_eh("removed %p\n", ud);
-
                wake_up(&ud->eh_waitq);
        }
 }
index 20e3d4609583848f8a14271d5c4bf3ffb8776123..d11f3f8dad4045e9c51bce1789b9473b60237f61 100644 (file)
@@ -354,6 +354,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                usbip_dbg_vhci_rh(" ClearHubFeature\n");
                break;
        case ClearPortFeature:
+               if (rhport < 0)
+                       goto error;
                switch (wValue) {
                case USB_PORT_FEAT_SUSPEND:
                        if (hcd->speed == HCD_USB3) {
@@ -511,11 +513,16 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                                goto error;
                        }
 
+                       if (rhport < 0)
+                               goto error;
+
                        vhci_hcd->port_status[rhport] |= USB_PORT_STAT_SUSPEND;
                        break;
                case USB_PORT_FEAT_POWER:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_POWER\n");
+                       if (rhport < 0)
+                               goto error;
                        if (hcd->speed == HCD_USB3)
                                vhci_hcd->port_status[rhport] |= USB_SS_PORT_STAT_POWER;
                        else
@@ -524,6 +531,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                case USB_PORT_FEAT_BH_PORT_RESET:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_BH_PORT_RESET\n");
+                       if (rhport < 0)
+                               goto error;
                        /* Applicable only for USB3.0 hub */
                        if (hcd->speed != HCD_USB3) {
                                pr_err("USB_PORT_FEAT_BH_PORT_RESET req not "
@@ -534,6 +543,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                case USB_PORT_FEAT_RESET:
                        usbip_dbg_vhci_rh(
                                " SetPortFeature: USB_PORT_FEAT_RESET\n");
+                       if (rhport < 0)
+                               goto error;
                        /* if it's already enabled, disable */
                        if (hcd->speed == HCD_USB3) {
                                vhci_hcd->port_status[rhport] = 0;
@@ -554,6 +565,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                default:
                        usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
                                          wValue);
+                       if (rhport < 0)
+                               goto error;
                        if (hcd->speed == HCD_USB3) {
                                if ((vhci_hcd->port_status[rhport] &
                                     USB_SS_PORT_STAT_POWER) != 0) {
index 190dbf8cfcb564f3c36c5504472b4dfec8070f51..2f3856a95856be43bcbfc6a4c3865f7099045368 100644 (file)
@@ -114,7 +114,7 @@ static void vbg_guest_mappings_init(struct vbg_dev *gdev)
        }
 
 out:
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        kfree(pages);
 }
 
@@ -144,7 +144,7 @@ static void vbg_guest_mappings_exit(struct vbg_dev *gdev)
 
        rc = vbg_req_perform(gdev, req);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        if (rc < 0) {
                vbg_err("%s error: %d\n", __func__, rc);
@@ -214,8 +214,8 @@ static int vbg_report_guest_info(struct vbg_dev *gdev)
        ret = vbg_status_code_to_errno(rc);
 
 out_free:
-       kfree(req2);
-       kfree(req1);
+       vbg_req_free(req2, sizeof(*req2));
+       vbg_req_free(req1, sizeof(*req1));
        return ret;
 }
 
@@ -245,7 +245,7 @@ static int vbg_report_driver_status(struct vbg_dev *gdev, bool active)
        if (rc == VERR_NOT_IMPLEMENTED) /* Compatibility with older hosts. */
                rc = VINF_SUCCESS;
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return vbg_status_code_to_errno(rc);
 }
@@ -431,7 +431,7 @@ static int vbg_heartbeat_host_config(struct vbg_dev *gdev, bool enabled)
        rc = vbg_req_perform(gdev, req);
        do_div(req->interval_ns, 1000000); /* ns -> ms */
        gdev->heartbeat_interval_ms = req->interval_ns;
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return vbg_status_code_to_errno(rc);
 }
@@ -454,12 +454,6 @@ static int vbg_heartbeat_init(struct vbg_dev *gdev)
        if (ret < 0)
                return ret;
 
-       /*
-        * Preallocate the request to use it from the timer callback because:
-        *    1) on Windows vbg_req_alloc must be called at IRQL <= APC_LEVEL
-        *       and the timer callback runs at DISPATCH_LEVEL;
-        *    2) avoid repeated allocations.
-        */
        gdev->guest_heartbeat_req = vbg_req_alloc(
                                        sizeof(*gdev->guest_heartbeat_req),
                                        VMMDEVREQ_GUEST_HEARTBEAT);
@@ -481,8 +475,8 @@ static void vbg_heartbeat_exit(struct vbg_dev *gdev)
 {
        del_timer_sync(&gdev->heartbeat_timer);
        vbg_heartbeat_host_config(gdev, false);
-       kfree(gdev->guest_heartbeat_req);
-
+       vbg_req_free(gdev->guest_heartbeat_req,
+                    sizeof(*gdev->guest_heartbeat_req));
 }
 
 /**
@@ -543,7 +537,7 @@ static int vbg_reset_host_event_filter(struct vbg_dev *gdev,
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
@@ -617,7 +611,7 @@ static int vbg_set_session_event_filter(struct vbg_dev *gdev,
 
 out:
        mutex_unlock(&gdev->session_mutex);
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return ret;
 }
@@ -642,7 +636,7 @@ static int vbg_reset_host_capabilities(struct vbg_dev *gdev)
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
@@ -712,7 +706,7 @@ static int vbg_set_session_capabilities(struct vbg_dev *gdev,
 
 out:
        mutex_unlock(&gdev->session_mutex);
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
 
        return ret;
 }
@@ -733,8 +727,10 @@ static int vbg_query_host_version(struct vbg_dev *gdev)
 
        rc = vbg_req_perform(gdev, req);
        ret = vbg_status_code_to_errno(rc);
-       if (ret)
+       if (ret) {
+               vbg_err("%s error: %d\n", __func__, rc);
                goto out;
+       }
 
        snprintf(gdev->host_version, sizeof(gdev->host_version), "%u.%u.%ur%u",
                 req->major, req->minor, req->build, req->revision);
@@ -749,7 +745,7 @@ static int vbg_query_host_version(struct vbg_dev *gdev)
        }
 
 out:
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return ret;
 }
 
@@ -847,11 +843,16 @@ int vbg_core_init(struct vbg_dev *gdev, u32 fixed_events)
        return 0;
 
 err_free_reqs:
-       kfree(gdev->mouse_status_req);
-       kfree(gdev->ack_events_req);
-       kfree(gdev->cancel_req);
-       kfree(gdev->mem_balloon.change_req);
-       kfree(gdev->mem_balloon.get_req);
+       vbg_req_free(gdev->mouse_status_req,
+                    sizeof(*gdev->mouse_status_req));
+       vbg_req_free(gdev->ack_events_req,
+                    sizeof(*gdev->ack_events_req));
+       vbg_req_free(gdev->cancel_req,
+                    sizeof(*gdev->cancel_req));
+       vbg_req_free(gdev->mem_balloon.change_req,
+                    sizeof(*gdev->mem_balloon.change_req));
+       vbg_req_free(gdev->mem_balloon.get_req,
+                    sizeof(*gdev->mem_balloon.get_req));
        return ret;
 }
 
@@ -872,11 +873,16 @@ void vbg_core_exit(struct vbg_dev *gdev)
        vbg_reset_host_capabilities(gdev);
        vbg_core_set_mouse_status(gdev, 0);
 
-       kfree(gdev->mouse_status_req);
-       kfree(gdev->ack_events_req);
-       kfree(gdev->cancel_req);
-       kfree(gdev->mem_balloon.change_req);
-       kfree(gdev->mem_balloon.get_req);
+       vbg_req_free(gdev->mouse_status_req,
+                    sizeof(*gdev->mouse_status_req));
+       vbg_req_free(gdev->ack_events_req,
+                    sizeof(*gdev->ack_events_req));
+       vbg_req_free(gdev->cancel_req,
+                    sizeof(*gdev->cancel_req));
+       vbg_req_free(gdev->mem_balloon.change_req,
+                    sizeof(*gdev->mem_balloon.change_req));
+       vbg_req_free(gdev->mem_balloon.get_req,
+                    sizeof(*gdev->mem_balloon.get_req));
 }
 
 /**
@@ -1415,7 +1421,7 @@ static int vbg_ioctl_write_core_dump(struct vbg_dev *gdev,
        req->flags = dump->u.in.flags;
        dump->hdr.rc = vbg_req_perform(gdev, req);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return 0;
 }
 
@@ -1513,7 +1519,7 @@ int vbg_core_set_mouse_status(struct vbg_dev *gdev, u32 features)
        if (rc < 0)
                vbg_err("%s error, rc: %d\n", __func__, rc);
 
-       kfree(req);
+       vbg_req_free(req, sizeof(*req));
        return vbg_status_code_to_errno(rc);
 }
 
index 6c784bf4fa6d50c23ff4c32067d5892aca7b5adb..7ad9ec45bfa9d649627f45e9410aebff43cd22c7 100644 (file)
@@ -171,4 +171,13 @@ irqreturn_t vbg_core_isr(int irq, void *dev_id);
 
 void vbg_linux_mouse_event(struct vbg_dev *gdev);
 
+/* Private (non exported) functions form vboxguest_utils.c */
+void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
+void vbg_req_free(void *req, size_t len);
+int vbg_req_perform(struct vbg_dev *gdev, void *req);
+int vbg_hgcm_call32(
+       struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms,
+       struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count,
+       int *vbox_status);
+
 #endif
index 82e280d38cc2e1bd1da2b2e6847b3174b5854548..398d2269323471305088762ba92ed9da3d53d9af 100644 (file)
@@ -87,6 +87,7 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
        struct vbg_session *session = filp->private_data;
        size_t returned_size, size;
        struct vbg_ioctl_hdr hdr;
+       bool is_vmmdev_req;
        int ret = 0;
        void *buf;
 
@@ -106,8 +107,17 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
        if (size > SZ_16M)
                return -E2BIG;
 
-       /* __GFP_DMA32 because IOCTL_VMMDEV_REQUEST passes this to the host */
-       buf = kmalloc(size, GFP_KERNEL | __GFP_DMA32);
+       /*
+        * IOCTL_VMMDEV_REQUEST needs the buffer to be below 4G to avoid
+        * the need for a bounce-buffer and another copy later on.
+        */
+       is_vmmdev_req = (req & ~IOCSIZE_MASK) == VBG_IOCTL_VMMDEV_REQUEST(0) ||
+                        req == VBG_IOCTL_VMMDEV_REQUEST_BIG;
+
+       if (is_vmmdev_req)
+               buf = vbg_req_alloc(size, VBG_IOCTL_HDR_TYPE_DEFAULT);
+       else
+               buf = kmalloc(size, GFP_KERNEL);
        if (!buf)
                return -ENOMEM;
 
@@ -132,7 +142,10 @@ static long vbg_misc_device_ioctl(struct file *filp, unsigned int req,
                ret = -EFAULT;
 
 out:
-       kfree(buf);
+       if (is_vmmdev_req)
+               vbg_req_free(buf, size);
+       else
+               kfree(buf);
 
        return ret;
 }
index 0f0dab8023cf6dfd5cd47ecc507cae0a2df550d8..bf4474214b4d31bb708c3d9c302d6ce415e17c7a 100644 (file)
@@ -65,8 +65,9 @@ VBG_LOG(vbg_debug, pr_debug);
 void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type)
 {
        struct vmmdev_request_header *req;
+       int order = get_order(PAGE_ALIGN(len));
 
-       req = kmalloc(len, GFP_KERNEL | __GFP_DMA32);
+       req = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order);
        if (!req)
                return NULL;
 
@@ -82,6 +83,14 @@ void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type)
        return req;
 }
 
+void vbg_req_free(void *req, size_t len)
+{
+       if (!req)
+               return;
+
+       free_pages((unsigned long)req, get_order(PAGE_ALIGN(len)));
+}
+
 /* Note this function returns a VBox status code, not a negative errno!! */
 int vbg_req_perform(struct vbg_dev *gdev, void *req)
 {
@@ -137,7 +146,7 @@ int vbg_hgcm_connect(struct vbg_dev *gdev,
                rc = hgcm_connect->header.result;
        }
 
-       kfree(hgcm_connect);
+       vbg_req_free(hgcm_connect, sizeof(*hgcm_connect));
 
        *vbox_status = rc;
        return 0;
@@ -166,7 +175,7 @@ int vbg_hgcm_disconnect(struct vbg_dev *gdev, u32 client_id, int *vbox_status)
        if (rc >= 0)
                rc = hgcm_disconnect->header.result;
 
-       kfree(hgcm_disconnect);
+       vbg_req_free(hgcm_disconnect, sizeof(*hgcm_disconnect));
 
        *vbox_status = rc;
        return 0;
@@ -623,7 +632,7 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function,
        }
 
        if (!leak_it)
-               kfree(call);
+               vbg_req_free(call, size);
 
 free_bounce_bufs:
        if (bounce_bufs) {
index 7e72348639e4bcbf523ec4bec3a589fbcd643c7c..315f7e63e7cca3b64eed882e8dc0c5fefbebe645 100644 (file)
@@ -228,7 +228,15 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
 
 static bool ceph_vxattrcb_quota_exists(struct ceph_inode_info *ci)
 {
-       return (ci->i_max_files || ci->i_max_bytes);
+       bool ret = false;
+       spin_lock(&ci->i_ceph_lock);
+       if ((ci->i_max_files || ci->i_max_bytes) &&
+           ci->i_vino.snap == CEPH_NOSNAP &&
+           ci->i_snap_realm &&
+           ci->i_snap_realm->ino == ci->i_vino.ino)
+               ret = true;
+       spin_unlock(&ci->i_ceph_lock);
+       return ret;
 }
 
 static size_t ceph_vxattrcb_quota(struct ceph_inode_info *ci, char *val,
@@ -1008,14 +1016,19 @@ int __ceph_setxattr(struct inode *inode, const char *name,
        char *newval = NULL;
        struct ceph_inode_xattr *xattr = NULL;
        int required_blob_size;
+       bool check_realm = false;
        bool lock_snap_rwsem = false;
 
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
 
        vxattr = ceph_match_vxattr(inode, name);
-       if (vxattr && vxattr->readonly)
-               return -EOPNOTSUPP;
+       if (vxattr) {
+               if (vxattr->readonly)
+                       return -EOPNOTSUPP;
+               if (value && !strncmp(vxattr->name, "ceph.quota", 10))
+                       check_realm = true;
+       }
 
        /* pass any unhandled ceph.* xattrs through to the MDS */
        if (!strncmp(name, XATTR_CEPH_PREFIX, XATTR_CEPH_PREFIX_LEN))
@@ -1109,6 +1122,15 @@ int __ceph_setxattr(struct inode *inode, const char *name,
                err = -EBUSY;
        } else {
                err = ceph_sync_setxattr(inode, name, value, size, flags);
+               if (err >= 0 && check_realm) {
+                       /* check if snaprealm was created for quota inode */
+                       spin_lock(&ci->i_ceph_lock);
+                       if ((ci->i_max_files || ci->i_max_bytes) &&
+                           !(ci->i_snap_realm &&
+                             ci->i_snap_realm->ino == ci->i_vino.ino))
+                               err = -EOPNOTSUPP;
+                       spin_unlock(&ci->i_ceph_lock);
+               }
        }
 out:
        ceph_free_cap_flush(prealloc_cf);
index 6d3e40d7029c47c6abd7264e8a8aa0cf526f4ee5..1529a088383d048554cfd129de7b8898aa12f6e1 100644 (file)
@@ -455,6 +455,9 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
                server->sign = true;
        }
 
+       if (cifs_rdma_enabled(server) && server->sign)
+               cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
+
        return 0;
 }
 
index e8830f076a7f16a056f7eec3cf025e0e30bff9e8..a5aa158d535a70a2247419152d01b64d553c1596 100644 (file)
@@ -2959,6 +2959,22 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                }
        }
 
+       if (volume_info->seal) {
+               if (ses->server->vals->protocol_id == 0) {
+                       cifs_dbg(VFS,
+                                "SMB3 or later required for encryption\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               } else if (tcon->ses->server->capabilities &
+                                       SMB2_GLOBAL_CAP_ENCRYPTION)
+                       tcon->seal = true;
+               else {
+                       cifs_dbg(VFS, "Encryption is not supported on share\n");
+                       rc = -EOPNOTSUPP;
+                       goto out_fail;
+               }
+       }
+
        /*
         * BB Do we need to wrap session_mutex around this TCon call and Unix
         * SetFS as we do on SessSetup and reconnect?
@@ -3007,22 +3023,6 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
                tcon->use_resilient = true;
        }
 
-       if (volume_info->seal) {
-               if (ses->server->vals->protocol_id == 0) {
-                       cifs_dbg(VFS,
-                                "SMB3 or later required for encryption\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               } else if (tcon->ses->server->capabilities &
-                                       SMB2_GLOBAL_CAP_ENCRYPTION)
-                       tcon->seal = true;
-               else {
-                       cifs_dbg(VFS, "Encryption is not supported on share\n");
-                       rc = -EOPNOTSUPP;
-                       goto out_fail;
-               }
-       }
-
        /*
         * We can have only one retry value for a connection to a share so for
         * resources mounted more than once to the same server share the last
index 38ebf3f357d29233571c2319fb45940f1cc1f5fe..b76b85881dcc668e87f99ee55b6bb4463f25510e 100644 (file)
@@ -252,9 +252,14 @@ smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
        wsize = min_t(unsigned int, wsize, server->max_write);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               wsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       wsize = min_t(unsigned int,
+                               wsize, server->smbd_conn->max_fragmented_send_size);
+               else
+                       wsize = min_t(unsigned int,
                                wsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
                wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
@@ -272,9 +277,14 @@ smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
        rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
        rsize = min_t(unsigned int, rsize, server->max_read);
 #ifdef CONFIG_CIFS_SMB_DIRECT
-       if (server->rdma)
-               rsize = min_t(unsigned int,
+       if (server->rdma) {
+               if (server->sign)
+                       rsize = min_t(unsigned int,
+                               rsize, server->smbd_conn->max_fragmented_recv_size);
+               else
+                       rsize = min_t(unsigned int,
                                rsize, server->smbd_conn->max_readwrite_size);
+       }
 #endif
 
        if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
index 0f044c4a2dc9b5b625e9cae21d34344692b76d23..60db51bae0e3a88cec2147cf9d7e709bebb0c7fd 100644 (file)
@@ -383,10 +383,10 @@ static void
 build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
 {
        pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
-       pneg_ctxt->DataLength = cpu_to_le16(6);
-       pneg_ctxt->CipherCount = cpu_to_le16(2);
-       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
-       pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
+       pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + le16 cipher */
+       pneg_ctxt->CipherCount = cpu_to_le16(1);
+/* pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;*/ /* not supported yet */
+       pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM;
 }
 
 static void
@@ -444,6 +444,7 @@ static int decode_encrypt_ctx(struct TCP_Server_Info *server,
                return -EINVAL;
        }
        server->cipher_type = ctxt->Ciphers[0];
+       server->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
        return 0;
 }
 
@@ -2590,7 +2591,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
         * If we want to do a RDMA write, fill in and append
         * smbd_buffer_descriptor_v1 to the end of read request
         */
-       if (server->rdma && rdata &&
+       if (server->rdma && rdata && !server->sign &&
                rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;
@@ -2968,7 +2969,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
         * If we want to do a server RDMA read, fill in and append
         * smbd_buffer_descriptor_v1 to the end of write request
         */
-       if (server->rdma && wdata->bytes >=
+       if (server->rdma && !server->sign && wdata->bytes >=
                server->smbd_conn->rdma_readwrite_threshold) {
 
                struct smbd_buffer_descriptor_v1 *v1;
index 6093e5142b2bc3792cf40afb7f7abbc02b60bbb4..d28f358022c507cc0dc55dbebb382ed29dec708d 100644 (file)
@@ -297,7 +297,7 @@ struct smb2_encryption_neg_context {
        __le16  DataLength;
        __le32  Reserved;
        __le16  CipherCount; /* AES-128-GCM and AES-128-CCM */
-       __le16  Ciphers[2]; /* Ciphers[0] since only one used now */
+       __le16  Ciphers[1]; /* Ciphers[0] since only one used now */
 } __packed;
 
 struct smb2_negotiate_rsp {
index 87817ddcc096d49036fb4b3421a2bbb3b2fe6b8a..c62f7c95683c513213bc786152f78b60a2f8fbd6 100644 (file)
@@ -2086,7 +2086,7 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
        int start, i, j;
        int max_iov_size =
                info->max_send_size - sizeof(struct smbd_data_transfer);
-       struct kvec iov[SMBDIRECT_MAX_SGE];
+       struct kvec *iov;
        int rc;
 
        info->smbd_send_pending++;
@@ -2096,32 +2096,20 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
        }
 
        /*
-        * This usually means a configuration error
-        * We use RDMA read/write for packet size > rdma_readwrite_threshold
-        * as long as it's properly configured we should never get into this
-        * situation
-        */
-       if (rqst->rq_nvec + rqst->rq_npages > SMBDIRECT_MAX_SGE) {
-               log_write(ERR, "maximum send segment %x exceeding %x\n",
-                        rqst->rq_nvec + rqst->rq_npages, SMBDIRECT_MAX_SGE);
-               rc = -EINVAL;
-               goto done;
-       }
-
-       /*
-        * Remove the RFC1002 length defined in MS-SMB2 section 2.1
-        * It is used only for TCP transport
+        * Skip the RFC1002 length defined in MS-SMB2 section 2.1
+        * It is used only for TCP transport in the iov[0]
         * In future we may want to add a transport layer under protocol
         * layer so this will only be issued to TCP transport
         */
-       iov[0].iov_base = (char *)rqst->rq_iov[0].iov_base + 4;
-       iov[0].iov_len = rqst->rq_iov[0].iov_len - 4;
-       buflen += iov[0].iov_len;
+
+       if (rqst->rq_iov[0].iov_len != 4) {
+               log_write(ERR, "expected the pdu length in 1st iov, but got %zu\n", rqst->rq_iov[0].iov_len);
+               return -EINVAL;
+       }
+       iov = &rqst->rq_iov[1];
 
        /* total up iov array first */
-       for (i = 1; i < rqst->rq_nvec; i++) {
-               iov[i].iov_base = rqst->rq_iov[i].iov_base;
-               iov[i].iov_len = rqst->rq_iov[i].iov_len;
+       for (i = 0; i < rqst->rq_nvec-1; i++) {
                buflen += iov[i].iov_len;
        }
 
@@ -2198,14 +2186,14 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
                                                goto done;
                                }
                                i++;
-                               if (i == rqst->rq_nvec)
+                               if (i == rqst->rq_nvec-1)
                                        break;
                        }
                        start = i;
                        buflen = 0;
                } else {
                        i++;
-                       if (i == rqst->rq_nvec) {
+                       if (i == rqst->rq_nvec-1) {
                                /* send out all remaining vecs */
                                remaining_data_length -= buflen;
                                log_write(INFO,
index 8f6f25918229d9aeb680173a87cf9d684d2eb5c8..927226a2122f4dde57955fe805013d14fd6237df 100644 (file)
@@ -753,7 +753,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
                goto out;
 
 #ifdef CONFIG_CIFS_SMB311
-       if (ses->status == CifsNew)
+       if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP))
                smb311_update_preauth_hash(ses, rqst->rq_iov+1,
                                           rqst->rq_nvec-1);
 #endif
@@ -798,7 +798,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
                *resp_buf_type = CIFS_SMALL_BUFFER;
 
 #ifdef CONFIG_CIFS_SMB311
-       if (ses->status == CifsNew) {
+       if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) {
                struct kvec iov = {
                        .iov_base = buf + 4,
                        .iov_len = get_rfc1002_length(buf)
@@ -834,8 +834,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
        if (n_vec + 1 > CIFS_MAX_IOV_SIZE) {
                new_iov = kmalloc(sizeof(struct kvec) * (n_vec + 1),
                                  GFP_KERNEL);
-               if (!new_iov)
+               if (!new_iov) {
+                       /* otherwise cifs_send_recv below sets resp_buf_type */
+                       *resp_buf_type = CIFS_NO_BUFFER;
                        return -ENOMEM;
+               }
        } else
                new_iov = s_iov;
 
index a33d8fb1bf2a7fc3ac13459e526fb9ec88373db3..508b905d744d752bfa671f4a8a09ea066ad8c25a 100644 (file)
@@ -321,6 +321,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        struct ext4_sb_info *sbi = EXT4_SB(sb);
        ext4_grpblk_t offset;
        ext4_grpblk_t next_zero_bit;
+       ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
        ext4_fsblk_t blk;
        ext4_fsblk_t group_first_block;
 
@@ -338,7 +339,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether block bitmap block number is set */
        blk = ext4_block_bitmap(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
            !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
                /* bad block bitmap */
                return blk;
@@ -346,7 +347,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether the inode bitmap block number is set */
        blk = ext4_inode_bitmap(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
            !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
                /* bad block bitmap */
                return blk;
@@ -354,8 +355,8 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
        /* check whether the inode table block number is set */
        blk = ext4_inode_table(sb, desc);
        offset = blk - group_first_block;
-       if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
-           EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize)
+       if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
+           EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
                return blk;
        next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
                        EXT4_B2C(sbi, offset + sbi->s_itb_per_group),
index 0a7315961bac6ebbca0c2bfe83cc3aba8fc5c807..c969275ce3ee7469167a6921e8fa22e4c91ed3a2 100644 (file)
@@ -5329,8 +5329,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
        stop = le32_to_cpu(extent->ee_block);
 
        /*
-        * In case of left shift, Don't start shifting extents until we make
-        * sure the hole is big enough to accommodate the shift.
+       * For left shifts, make sure the hole on the left is big enough to
+       * accommodate the shift.  For right shifts, make sure the last extent
+       * won't be shifted beyond EXT_MAX_BLOCKS.
        */
        if (SHIFT == SHIFT_LEFT) {
                path = ext4_find_extent(inode, start - 1, &path,
@@ -5350,9 +5351,14 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle,
 
                if ((start == ex_start && shift > ex_start) ||
                    (shift > start - ex_end)) {
-                       ext4_ext_drop_refs(path);
-                       kfree(path);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto out;
+               }
+       } else {
+               if (shift > EXT_MAX_BLOCKS -
+                   (stop + ext4_ext_get_actual_len(extent))) {
+                       ret = -EINVAL;
+                       goto out;
                }
        }
 
index 185f7e61f4cfe00531e71e772a519af005f6bd69..eb104e8476f040e61253a6676c93e882e5a22314 100644 (file)
@@ -5886,5 +5886,6 @@ static void __exit ext4_exit_fs(void)
 MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
 MODULE_DESCRIPTION("Fourth Extended Filesystem");
 MODULE_LICENSE("GPL");
+MODULE_SOFTDEP("pre: crc32c");
 module_init(ext4_init_fs)
 module_exit(ext4_exit_fs)
index ac311037d7a59b03d6403a65c56c7978697463c6..8aa453784402bbed8d33aa76d025071bf6523c75 100644 (file)
@@ -532,6 +532,7 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
         */
        ret = start_this_handle(journal, handle, GFP_NOFS);
        if (ret < 0) {
+               handle->h_journal = journal;
                jbd2_journal_free_reserved(handle);
                return ret;
        }
index 278841c75b97b0f55431e75c3a172a041f43f94b..af240573e48295687e4403b0bcc11875d5da2e82 100644 (file)
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
-#define EARLYCON_TABLE() STRUCT_ALIGN();                       \
+#define EARLYCON_TABLE() . = ALIGN(8);                         \
                         VMLINUX_SYMBOL(__earlycon_table) = .;  \
                         KEEP(*(__earlycon_table))              \
                         VMLINUX_SYMBOL(__earlycon_table_end) = .;
index e518e4e3dfb50a83520a3b8100c3c27899c15bdf..4b1548129fa2b3e2b87565ec02d9dd5adb80ccb2 100644 (file)
@@ -37,10 +37,15 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
         * Our PSCI implementation stays the same across versions from
         * v0.2 onward, only adding the few mandatory functions (such
         * as FEATURES with 1.0) that are required by newer
-        * revisions. It is thus safe to return the latest.
+        * revisions. It is thus safe to return the latest, unless
+        * userspace has instructed us otherwise.
         */
-       if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
+       if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features)) {
+               if (vcpu->kvm->arch.psci_version)
+                       return vcpu->kvm->arch.psci_version;
+
                return KVM_ARM_PSCI_LATEST;
+       }
 
        return KVM_ARM_PSCI_0_1;
 }
@@ -48,4 +53,11 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
 
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
+struct kvm_one_reg;
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+
 #endif /* __KVM_ARM_PSCI_H__ */
index 0059b99e1f25db0ef52d09bf50e1239e2fbf14e9..477956990f5e3dc703df3154ef06ed3a5e3264d0 100644 (file)
@@ -256,7 +256,9 @@ enum probe_type {
  *             automatically.
  * @pm:                Power management operations of the device which matched
  *             this driver.
- * @coredump:  Called through sysfs to initiate a device coredump.
+ * @coredump:  Called when sysfs entry is written to. The device driver
+ *             is expected to call the dev_coredump API resulting in a
+ *             uevent.
  * @p:         Driver core's private data, no one other than the driver
  *             core can touch this.
  *
@@ -288,7 +290,7 @@ struct device_driver {
        const struct attribute_group **groups;
 
        const struct dev_pm_ops *pm;
-       int (*coredump) (struct device *dev);
+       void (*coredump) (struct device *dev);
 
        struct driver_private *p;
 };
index a2656c3ebe81cafaff88dc2329897b4a22d89edd..3892e9c8b2deb7993c11c1ac171375c7ba6e9e09 100644 (file)
@@ -161,9 +161,11 @@ struct hrtimer_clock_base {
 enum  hrtimer_base_type {
        HRTIMER_BASE_MONOTONIC,
        HRTIMER_BASE_REALTIME,
+       HRTIMER_BASE_BOOTTIME,
        HRTIMER_BASE_TAI,
        HRTIMER_BASE_MONOTONIC_SOFT,
        HRTIMER_BASE_REALTIME_SOFT,
+       HRTIMER_BASE_BOOTTIME_SOFT,
        HRTIMER_BASE_TAI_SOFT,
        HRTIMER_MAX_CLOCK_BASES,
 };
index b63fa457febd8d5d379ffe891e981ea2c8e912c8..3529683f691ef90c10f8ba89211341ceb60a1fe1 100644 (file)
@@ -85,6 +85,7 @@ struct flchip {
        unsigned int write_suspended:1;
        unsigned int erase_suspended:1;
        unsigned long in_progress_block_addr;
+       unsigned long in_progress_block_mask;
 
        struct mutex mutex;
        wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
index 1d356105f25a1680b05a6119fa1d9efba578b6b6..b4c9fda9d8335bd3b20611d9684645dce3f8532c 100644 (file)
@@ -351,10 +351,10 @@ struct earlycon_id {
        char    name[16];
        char    compatible[128];
        int     (*setup)(struct earlycon_device *, const char *options);
-} __aligned(32);
+};
 
-extern const struct earlycon_id __earlycon_table[];
-extern const struct earlycon_id __earlycon_table_end[];
+extern const struct earlycon_id *__earlycon_table[];
+extern const struct earlycon_id *__earlycon_table_end[];
 
 #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
 #define EARLYCON_USED_OR_UNUSED        __used
@@ -362,12 +362,19 @@ extern const struct earlycon_id __earlycon_table_end[];
 #define EARLYCON_USED_OR_UNUSED        __maybe_unused
 #endif
 
-#define OF_EARLYCON_DECLARE(_name, compat, fn)                         \
-       static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
-            EARLYCON_USED_OR_UNUSED __section(__earlycon_table)        \
+#define _OF_EARLYCON_DECLARE(_name, compat, fn, unique_id)             \
+       static const struct earlycon_id unique_id                       \
+            EARLYCON_USED_OR_UNUSED __initconst                        \
                = { .name = __stringify(_name),                         \
                    .compatible = compat,                               \
-                   .setup = fn  }
+                   .setup = fn  };                                     \
+       static const struct earlycon_id EARLYCON_USED_OR_UNUSED         \
+               __section(__earlycon_table)                             \
+               * const __PASTE(__p, unique_id) = &unique_id
+
+#define OF_EARLYCON_DECLARE(_name, compat, fn)                         \
+       _OF_EARLYCON_DECLARE(_name, compat, fn,                         \
+                            __UNIQUE_ID(__earlycon_##_name))
 
 #define EARLYCON_DECLARE(_name, fn)    OF_EARLYCON_DECLARE(_name, "", fn)
 
index e8f0f852968f1326edb7b261708d5a5cee49f030..c0c5c5b73dc0b0949043881e247a90aff5cf8a03 100644 (file)
@@ -50,9 +50,9 @@ partial_name_hash(unsigned long c, unsigned long prevhash)
  * losing bits).  This also has the property (wanted by the dcache)
  * that the msbits make a good hash table index.
  */
-static inline unsigned long end_name_hash(unsigned long hash)
+static inline unsigned int end_name_hash(unsigned long hash)
 {
-       return __hash_32((unsigned int)hash);
+       return hash_long(hash, 32);
 }
 
 /*
index 45bc6b37649294788e1061f8dd626c5609e167b9..53604b087f2c0b24993ea357b42103a8e07a4971 100644 (file)
@@ -60,6 +60,81 @@ struct ti_emif_pm_functions {
        u32 abort_sr;
 } __packed __aligned(8);
 
+static inline void ti_emif_asm_offsets(void)
+{
+       DEFINE(EMIF_SDCFG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_sdcfg_val));
+       DEFINE(EMIF_TIMING1_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing1_val));
+       DEFINE(EMIF_TIMING2_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing2_val));
+       DEFINE(EMIF_TIMING3_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_timing3_val));
+       DEFINE(EMIF_REF_CTRL_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ref_ctrl_val));
+       DEFINE(EMIF_ZQCFG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_zqcfg_val));
+       DEFINE(EMIF_PMCR_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_pmcr_val));
+       DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val));
+       DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl));
+       DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh));
+       DEFINE(EMIF_COS_CONFIG_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_cos_config));
+       DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping));
+       DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map));
+       DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map));
+       DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ocp_config_val));
+       DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim));
+       DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw));
+       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val));
+       DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw));
+       DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1));
+       DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET,
+              offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals));
+       DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3));
+
+       BLANK();
+
+       DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt));
+       DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys));
+       DEFINE(EMIF_PM_CONFIG_OFFSET,
+              offsetof(struct ti_emif_pm_data, ti_emif_sram_config));
+       DEFINE(EMIF_PM_REGS_VIRT_OFFSET,
+              offsetof(struct ti_emif_pm_data, regs_virt));
+       DEFINE(EMIF_PM_REGS_PHYS_OFFSET,
+              offsetof(struct ti_emif_pm_data, regs_phys));
+       DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data));
+
+       BLANK();
+
+       DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET,
+              offsetof(struct ti_emif_pm_functions, save_context));
+       DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET,
+              offsetof(struct ti_emif_pm_functions, restore_context));
+       DEFINE(EMIF_PM_ENTER_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, enter_sr));
+       DEFINE(EMIF_PM_EXIT_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, exit_sr));
+       DEFINE(EMIF_PM_ABORT_SR_OFFSET,
+              offsetof(struct ti_emif_pm_functions, abort_sr));
+       DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions));
+}
+
 struct gen_pool;
 
 int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst);
index 4b3dca173e8959a307785a1a1459654eadf62838..7acb953298a73118028ae04052fab9249529380f 100644 (file)
@@ -52,7 +52,6 @@ struct tk_read_base {
  * @offs_real:         Offset clock monotonic -> clock realtime
  * @offs_boot:         Offset clock monotonic -> clock boottime
  * @offs_tai:          Offset clock monotonic -> clock tai
- * @time_suspended:    Accumulated suspend time
  * @tai_offset:                The current UTC to TAI offset in seconds
  * @clock_was_set_seq: The sequence number of clock was set events
  * @cs_was_changed_seq:        The sequence number of clocksource change events
@@ -95,7 +94,6 @@ struct timekeeper {
        ktime_t                 offs_real;
        ktime_t                 offs_boot;
        ktime_t                 offs_tai;
-       ktime_t                 time_suspended;
        s32                     tai_offset;
        unsigned int            clock_was_set_seq;
        u8                      cs_was_changed_seq;
index 9737fbec7019bd02b9f6bf0ef9d34e1dc67fdaaa..588a0e4b1ab9336674b2bbc4f1fd0465b4d4a845 100644 (file)
@@ -33,25 +33,20 @@ extern void ktime_get_ts64(struct timespec64 *ts);
 extern time64_t ktime_get_seconds(void);
 extern time64_t __ktime_get_real_seconds(void);
 extern time64_t ktime_get_real_seconds(void);
-extern void ktime_get_active_ts64(struct timespec64 *ts);
 
 extern int __getnstimeofday64(struct timespec64 *tv);
 extern void getnstimeofday64(struct timespec64 *tv);
 extern void getboottime64(struct timespec64 *ts);
 
-#define ktime_get_real_ts64(ts)                getnstimeofday64(ts)
-
-/* Clock BOOTTIME compatibility wrappers */
-static inline void get_monotonic_boottime64(struct timespec64 *ts)
-{
-       ktime_get_ts64(ts);
-}
+#define ktime_get_real_ts64(ts)        getnstimeofday64(ts)
 
 /*
  * ktime_t based interfaces
  */
+
 enum tk_offsets {
        TK_OFFS_REAL,
+       TK_OFFS_BOOT,
        TK_OFFS_TAI,
        TK_OFFS_MAX,
 };
@@ -62,10 +57,6 @@ extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
 extern ktime_t ktime_get_raw(void);
 extern u32 ktime_get_resolution_ns(void);
 
-/* Clock BOOTTIME compatibility wrappers */
-static inline ktime_t ktime_get_boottime(void) { return ktime_get(); }
-static inline u64 ktime_get_boot_ns(void) { return ktime_get(); }
-
 /**
  * ktime_get_real - get the real (wall-) time in ktime_t format
  */
@@ -74,6 +65,17 @@ static inline ktime_t ktime_get_real(void)
        return ktime_get_with_offset(TK_OFFS_REAL);
 }
 
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+       return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
 /**
  * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
  */
@@ -100,6 +102,11 @@ static inline u64 ktime_get_real_ns(void)
        return ktime_to_ns(ktime_get_real());
 }
 
+static inline u64 ktime_get_boot_ns(void)
+{
+       return ktime_to_ns(ktime_get_boottime());
+}
+
 static inline u64 ktime_get_tai_ns(void)
 {
        return ktime_to_ns(ktime_get_clocktai());
@@ -112,11 +119,17 @@ static inline u64 ktime_get_raw_ns(void)
 
 extern u64 ktime_get_mono_fast_ns(void);
 extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
 extern u64 ktime_get_real_fast_ns(void);
 
 /*
  * timespec64 interfaces utilizing the ktime based ones
  */
+static inline void get_monotonic_boottime64(struct timespec64 *ts)
+{
+       *ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
 static inline void timekeeping_clocktai64(struct timespec64 *ts)
 {
        *ts = ktime_to_timespec64(ktime_get_clocktai());
index 47f8af22f2168f0376d77068ecbc2df930ae8f79..1dd587ba6d882bb882b44680ec1acebb314c4364 100644 (file)
@@ -701,7 +701,7 @@ extern int tty_unregister_ldisc(int disc);
 extern int tty_set_ldisc(struct tty_struct *tty, int disc);
 extern int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty);
 extern void tty_ldisc_release(struct tty_struct *tty);
-extern void tty_ldisc_init(struct tty_struct *tty);
+extern int __must_check tty_ldisc_init(struct tty_struct *tty);
 extern void tty_ldisc_deinit(struct tty_struct *tty);
 extern int tty_ldisc_receive_buf(struct tty_ldisc *ld, const unsigned char *p,
                                 char *f, int count);
index c71def6b310f3edb0b11ccc485be7d770b919831..a240ed2a0372c20281e03a45fe49dea6a2fd60a3 100644 (file)
@@ -24,24 +24,6 @@ __printf(1, 2) void vbg_debug(const char *fmt, ...);
 #define vbg_debug pr_debug
 #endif
 
-/**
- * Allocate memory for generic request and initialize the request header.
- *
- * Return: the allocated memory
- * @len:               Size of memory block required for the request.
- * @req_type:          The generic request type.
- */
-void *vbg_req_alloc(size_t len, enum vmmdev_request_type req_type);
-
-/**
- * Perform a generic request.
- *
- * Return: VBox status code
- * @gdev:              The Guest extension device.
- * @req:               Pointer to the request structure.
- */
-int vbg_req_perform(struct vbg_dev *gdev, void *req);
-
 int vbg_hgcm_connect(struct vbg_dev *gdev,
                     struct vmmdev_hgcm_service_location *loc,
                     u32 *client_id, int *vbox_status);
@@ -52,11 +34,6 @@ int vbg_hgcm_call(struct vbg_dev *gdev, u32 client_id, u32 function,
                  u32 timeout_ms, struct vmmdev_hgcm_function_parameter *parms,
                  u32 parm_count, int *vbox_status);
 
-int vbg_hgcm_call32(
-       struct vbg_dev *gdev, u32 client_id, u32 function, u32 timeout_ms,
-       struct vmmdev_hgcm_function_parameter32 *parm32, u32 parm_count,
-       int *vbox_status);
-
 /**
  * Convert a VirtualBox status code to a standard Linux kernel return value.
  * Return: 0 or negative errno value.
index 50df5b28d2c9df6eb0cffb217104cdf8ee59e9ed..8ee8991aa099af3a1c9d8435bab12821dfef8928 100644 (file)
@@ -143,13 +143,13 @@ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node);
 static inline int rpi_firmware_property(struct rpi_firmware *fw, u32 tag,
                                        void *data, size_t len)
 {
-       return 0;
+       return -ENOSYS;
 }
 
 static inline int rpi_firmware_property_list(struct rpi_firmware *fw,
                                             void *data, size_t tag_size)
 {
-       return 0;
+       return -ENOSYS;
 }
 
 static inline struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
index ca13a44ae9d44e971a977e489244b831ac83040c..6011a58d3e2086886278b8f42582bfdc52784fd0 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <linux/wait.h>
+#include <linux/nospec.h>
 #include <sound/asound.h>
 
 #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
@@ -148,12 +149,14 @@ int snd_ctl_get_preferred_subdevice(struct snd_card *card, int type);
 
 static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-       return id->numid - kctl->id.numid;
+       unsigned int ioff = id->numid - kctl->id.numid;
+       return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
-       return id->index - kctl->id.index;
+       unsigned int ioff = id->index - kctl->id.index;
+       return array_index_nospec(ioff, kctl->count);
 }
 
 static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
index 1065006c9bf5890abdf99f9a4c444552af5542d1..b02c41e53d5616a3124e16dbec17250654a790b4 100644 (file)
@@ -676,6 +676,13 @@ struct kvm_ioeventfd {
        __u8  pad[36];
 };
 
+#define KVM_X86_DISABLE_EXITS_MWAIT          (1 << 0)
+#define KVM_X86_DISABLE_EXITS_HTL            (1 << 1)
+#define KVM_X86_DISABLE_EXITS_PAUSE          (1 << 2)
+#define KVM_X86_DISABLE_VALID_EXITS          (KVM_X86_DISABLE_EXITS_MWAIT | \
+                                              KVM_X86_DISABLE_EXITS_HTL | \
+                                              KVM_X86_DISABLE_EXITS_PAUSE)
+
 /* for KVM_ENABLE_CAP */
 struct kvm_enable_cap {
        /* in */
index 0f272818a4d27846ef96881c266d9713bbadb094..6b58371b1f0d5a1405328c5e4c43c15bc9588f9a 100644 (file)
@@ -780,24 +780,6 @@ enum {
        NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5,
 };
 
-/* proc/sys/net/irda */
-enum {
-       NET_IRDA_DISCOVERY=1,
-       NET_IRDA_DEVNAME=2,
-       NET_IRDA_DEBUG=3,
-       NET_IRDA_FAST_POLL=4,
-       NET_IRDA_DISCOVERY_SLOTS=5,
-       NET_IRDA_DISCOVERY_TIMEOUT=6,
-       NET_IRDA_SLOT_TIMEOUT=7,
-       NET_IRDA_MAX_BAUD_RATE=8,
-       NET_IRDA_MIN_TX_TURN_TIME=9,
-       NET_IRDA_MAX_TX_DATA_SIZE=10,
-       NET_IRDA_MAX_TX_WINDOW=11,
-       NET_IRDA_MAX_NOREPLY_TIME=12,
-       NET_IRDA_WARN_NOREPLY_TIME=13,
-       NET_IRDA_LAP_KEEPALIVE_TIME=14,
-};
-
 
 /* CTL_FS names: */
 enum
index 16a296612ba4b0df2359c67aa9c899bec6f719c6..4c0338ea308a67b3f7dfe179651c7a55322ce6fb 100644 (file)
@@ -73,7 +73,6 @@ struct __kernel_old_timeval {
  */
 #define CLOCK_SGI_CYCLE                        10
 #define CLOCK_TAI                      11
-#define CLOCK_MONOTONIC_ACTIVE         12
 
 #define MAX_CLOCKS                     16
 #define CLOCKS_MASK                    (CLOCK_REALTIME | CLOCK_MONOTONIC)
index a6e43a5806a11391b6606b42cc972b13f9eb3828..ce8066b881782f9db47c7fc85d8659e1b9cfe9ac 100644 (file)
@@ -1472,7 +1472,8 @@ static ssize_t module_sect_show(struct module_attribute *mattr,
 {
        struct module_sect_attr *sattr =
                container_of(mattr, struct module_sect_attr, mattr);
-       return sprintf(buf, "0x%pK\n", (void *)sattr->address);
+       return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
+                      (void *)sattr->address : NULL);
 }
 
 static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
index e8c0dab4fd653a84d316c458a1db767995b02b47..07148b4974516cec45b934e5ed5881e1554e7af0 100644 (file)
@@ -704,24 +704,6 @@ static const struct bin_table bin_net_netfilter_table[] = {
        {}
 };
 
-static const struct bin_table bin_net_irda_table[] = {
-       { CTL_INT,      NET_IRDA_DISCOVERY,             "discovery" },
-       { CTL_STR,      NET_IRDA_DEVNAME,               "devname" },
-       { CTL_INT,      NET_IRDA_DEBUG,                 "debug" },
-       { CTL_INT,      NET_IRDA_FAST_POLL,             "fast_poll_increase" },
-       { CTL_INT,      NET_IRDA_DISCOVERY_SLOTS,       "discovery_slots" },
-       { CTL_INT,      NET_IRDA_DISCOVERY_TIMEOUT,     "discovery_timeout" },
-       { CTL_INT,      NET_IRDA_SLOT_TIMEOUT,          "slot_timeout" },
-       { CTL_INT,      NET_IRDA_MAX_BAUD_RATE,         "max_baud_rate" },
-       { CTL_INT,      NET_IRDA_MIN_TX_TURN_TIME,      "min_tx_turn_time" },
-       { CTL_INT,      NET_IRDA_MAX_TX_DATA_SIZE,      "max_tx_data_size" },
-       { CTL_INT,      NET_IRDA_MAX_TX_WINDOW,         "max_tx_window" },
-       { CTL_INT,      NET_IRDA_MAX_NOREPLY_TIME,      "max_noreply_time" },
-       { CTL_INT,      NET_IRDA_WARN_NOREPLY_TIME,     "warn_noreply_time" },
-       { CTL_INT,      NET_IRDA_LAP_KEEPALIVE_TIME,    "lap_keepalive_time" },
-       {}
-};
-
 static const struct bin_table bin_net_table[] = {
        { CTL_DIR,      NET_CORE,               "core",         bin_net_core_table },
        /* NET_ETHER not used */
@@ -743,7 +725,7 @@ static const struct bin_table bin_net_table[] = {
        { CTL_DIR,      NET_LLC,                "llc",          bin_net_llc_table },
        { CTL_DIR,      NET_NETFILTER,          "netfilter",    bin_net_netfilter_table },
        /* NET_DCCP "dccp" no longer used */
-       { CTL_DIR,      NET_IRDA,               "irda",         bin_net_irda_table },
+       /* NET_IRDA "irda" no longer used */
        { CTL_INT,      2089,                   "nf_conntrack_max" },
        {}
 };
index eda1210ce50f88dd88a53ab9fafbfeef5da021ca..14e858753d7689d96392402ebce61e0116574efa 100644 (file)
@@ -90,6 +90,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
                        .clockid = CLOCK_REALTIME,
                        .get_time = &ktime_get_real,
                },
+               {
+                       .index = HRTIMER_BASE_BOOTTIME,
+                       .clockid = CLOCK_BOOTTIME,
+                       .get_time = &ktime_get_boottime,
+               },
                {
                        .index = HRTIMER_BASE_TAI,
                        .clockid = CLOCK_TAI,
@@ -105,6 +110,11 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
                        .clockid = CLOCK_REALTIME,
                        .get_time = &ktime_get_real,
                },
+               {
+                       .index = HRTIMER_BASE_BOOTTIME_SOFT,
+                       .clockid = CLOCK_BOOTTIME,
+                       .get_time = &ktime_get_boottime,
+               },
                {
                        .index = HRTIMER_BASE_TAI_SOFT,
                        .clockid = CLOCK_TAI,
@@ -119,7 +129,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {
 
        [CLOCK_REALTIME]        = HRTIMER_BASE_REALTIME,
        [CLOCK_MONOTONIC]       = HRTIMER_BASE_MONOTONIC,
-       [CLOCK_BOOTTIME]        = HRTIMER_BASE_MONOTONIC,
+       [CLOCK_BOOTTIME]        = HRTIMER_BASE_BOOTTIME,
        [CLOCK_TAI]             = HRTIMER_BASE_TAI,
 };
 
@@ -571,12 +581,14 @@ __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base, unsigned int active_
 static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
 {
        ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;
+       ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset;
        ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset;
 
        ktime_t now = ktime_get_update_offsets_now(&base->clock_was_set_seq,
-                                                  offs_real, offs_tai);
+                                           offs_real, offs_boot, offs_tai);
 
        base->clock_base[HRTIMER_BASE_REALTIME_SOFT].offset = *offs_real;
+       base->clock_base[HRTIMER_BASE_BOOTTIME_SOFT].offset = *offs_boot;
        base->clock_base[HRTIMER_BASE_TAI_SOFT].offset = *offs_tai;
 
        return now;
index e0dbae98db9d9b11cbcfa6695c850ad8f0c27b87..69a937c3cd81260e8a83942ea0d21750c86fa5be 100644 (file)
@@ -83,8 +83,6 @@ int do_clock_gettime(clockid_t which_clock, struct timespec64 *tp)
        case CLOCK_BOOTTIME:
                get_monotonic_boottime64(tp);
                break;
-       case CLOCK_MONOTONIC_ACTIVE:
-               ktime_get_active_ts64(tp);
        default:
                return -EINVAL;
        }
index b6899b5060bd8450a20ab8b90b626ddf8327bec7..10b7186d063830b9e45a84146ed243a9f0e80b07 100644 (file)
@@ -252,16 +252,15 @@ static int posix_get_coarse_res(const clockid_t which_clock, struct timespec64 *
        return 0;
 }
 
-static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
+static int posix_get_boottime(const clockid_t which_clock, struct timespec64 *tp)
 {
-       timekeeping_clocktai64(tp);
+       get_monotonic_boottime64(tp);
        return 0;
 }
 
-static int posix_get_monotonic_active(clockid_t which_clock,
-                                     struct timespec64 *tp)
+static int posix_get_tai(clockid_t which_clock, struct timespec64 *tp)
 {
-       ktime_get_active_ts64(tp);
+       timekeeping_clocktai64(tp);
        return 0;
 }
 
@@ -1317,9 +1316,19 @@ static const struct k_clock clock_tai = {
        .timer_arm              = common_hrtimer_arm,
 };
 
-static const struct k_clock clock_monotonic_active = {
+static const struct k_clock clock_boottime = {
        .clock_getres           = posix_get_hrtimer_res,
-       .clock_get              = posix_get_monotonic_active,
+       .clock_get              = posix_get_boottime,
+       .nsleep                 = common_nsleep,
+       .timer_create           = common_timer_create,
+       .timer_set              = common_timer_set,
+       .timer_get              = common_timer_get,
+       .timer_del              = common_timer_del,
+       .timer_rearm            = common_hrtimer_rearm,
+       .timer_forward          = common_hrtimer_forward,
+       .timer_remaining        = common_hrtimer_remaining,
+       .timer_try_to_cancel    = common_hrtimer_try_to_cancel,
+       .timer_arm              = common_hrtimer_arm,
 };
 
 static const struct k_clock * const posix_clocks[] = {
@@ -1330,11 +1339,10 @@ static const struct k_clock * const posix_clocks[] = {
        [CLOCK_MONOTONIC_RAW]           = &clock_monotonic_raw,
        [CLOCK_REALTIME_COARSE]         = &clock_realtime_coarse,
        [CLOCK_MONOTONIC_COARSE]        = &clock_monotonic_coarse,
-       [CLOCK_BOOTTIME]                = &clock_monotonic,
+       [CLOCK_BOOTTIME]                = &clock_boottime,
        [CLOCK_REALTIME_ALARM]          = &alarm_clock,
        [CLOCK_BOOTTIME_ALARM]          = &alarm_clock,
        [CLOCK_TAI]                     = &clock_tai,
-       [CLOCK_MONOTONIC_ACTIVE]        = &clock_monotonic_active,
 };
 
 static const struct k_clock *clockid_to_kclock(const clockid_t id)
index 099572ca4a8f239a54d88f37ce4ad1418c8aa483..49edc1c4f3e645894f839c40489ab81594a02398 100644 (file)
@@ -419,19 +419,6 @@ void tick_suspend_local(void)
        clockevents_shutdown(td->evtdev);
 }
 
-static void tick_forward_next_period(void)
-{
-       ktime_t delta, now = ktime_get();
-       u64 n;
-
-       delta = ktime_sub(now, tick_next_period);
-       n = ktime_divns(delta, tick_period);
-       tick_next_period += n * tick_period;
-       if (tick_next_period < now)
-               tick_next_period += tick_period;
-       tick_sched_forward_next_period();
-}
-
 /**
  * tick_resume_local - Resume the local tick device
  *
@@ -444,8 +431,6 @@ void tick_resume_local(void)
        struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
        bool broadcast = tick_resume_check_broadcast();
 
-       tick_forward_next_period();
-
        clockevents_tick_resume(td->evtdev);
        if (!broadcast) {
                if (td->mode == TICKDEV_MODE_PERIODIC)
index 21efab7485ca517bf6fd675233d1dd268e3ce252..e277284c2831c9c1dae2219c1a135e1f5dc8945d 100644 (file)
@@ -141,12 +141,6 @@ static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
 static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }
 #endif /* !(BROADCAST && ONESHOT) */
 
-#if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS)
-extern void tick_sched_forward_next_period(void);
-#else
-static inline void tick_sched_forward_next_period(void) { }
-#endif
-
 /* NO_HZ_FULL internal */
 #ifdef CONFIG_NO_HZ_FULL
 extern void tick_nohz_init(void);
index 646645e981f942480d49857fc84ef2d5bcd14791..da9455a6b42ba1f03cbfaf75f427e92f1241d2bb 100644 (file)
@@ -51,15 +51,6 @@ struct tick_sched *tick_get_tick_sched(int cpu)
  */
 static ktime_t last_jiffies_update;
 
-/*
- * Called after resume. Make sure that jiffies are not fast forwarded due to
- * clock monotonic being forwarded by the suspended time.
- */
-void tick_sched_forward_next_period(void)
-{
-       last_jiffies_update = tick_next_period;
-}
-
 /*
  * Must be called with interrupts disabled !
  */
@@ -804,12 +795,12 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
                return;
        }
 
-       hrtimer_set_expires(&ts->sched_timer, tick);
-
-       if (ts->nohz_mode == NOHZ_MODE_HIGHRES)
-               hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS_PINNED);
-       else
+       if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+               hrtimer_start(&ts->sched_timer, tick, HRTIMER_MODE_ABS_PINNED);
+       } else {
+               hrtimer_set_expires(&ts->sched_timer, tick);
                tick_program_event(tick, 1);
+       }
 }
 
 static void tick_nohz_retain_tick(struct tick_sched *ts)
index dcf7f20fcd12f281852cf653957bb4b29da05584..49cbceef5debc7c06aab4f4f5a2479b291855ee7 100644 (file)
@@ -138,12 +138,7 @@ static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec64 wtm)
 
 static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
 {
-       /* Update both bases so mono and raw stay coupled. */
-       tk->tkr_mono.base += delta;
-       tk->tkr_raw.base += delta;
-
-       /* Accumulate time spent in suspend */
-       tk->time_suspended += delta;
+       tk->offs_boot = ktime_add(tk->offs_boot, delta);
 }
 
 /*
@@ -473,6 +468,36 @@ u64 ktime_get_raw_fast_ns(void)
 }
 EXPORT_SYMBOL_GPL(ktime_get_raw_fast_ns);
 
+/**
+ * ktime_get_boot_fast_ns - NMI safe and fast access to boot clock.
+ *
+ * To keep it NMI safe since we're accessing from tracing, we're not using a
+ * separate timekeeper with updates to monotonic clock and boot offset
+ * protected with seqlocks. This has the following minor side effects:
+ *
+ * (1) Its possible that a timestamp be taken after the boot offset is updated
+ * but before the timekeeper is updated. If this happens, the new boot offset
+ * is added to the old timekeeping making the clock appear to update slightly
+ * earlier:
+ *    CPU 0                                        CPU 1
+ *    timekeeping_inject_sleeptime64()
+ *    __timekeeping_inject_sleeptime(tk, delta);
+ *                                                 timestamp();
+ *    timekeeping_update(tk, TK_CLEAR_NTP...);
+ *
+ * (2) On 32-bit systems, the 64-bit boot offset (tk->offs_boot) may be
+ * partially updated.  Since the tk->offs_boot update is a rare event, this
+ * should be a rare occurrence which postprocessing should be able to handle.
+ */
+u64 notrace ktime_get_boot_fast_ns(void)
+{
+       struct timekeeper *tk = &tk_core.timekeeper;
+
+       return (ktime_get_mono_fast_ns() + ktime_to_ns(tk->offs_boot));
+}
+EXPORT_SYMBOL_GPL(ktime_get_boot_fast_ns);
+
+
 /*
  * See comment for __ktime_get_fast_ns() vs. timestamp ordering
  */
@@ -764,6 +789,7 @@ EXPORT_SYMBOL_GPL(ktime_get_resolution_ns);
 
 static ktime_t *offsets[TK_OFFS_MAX] = {
        [TK_OFFS_REAL]  = &tk_core.timekeeper.offs_real,
+       [TK_OFFS_BOOT]  = &tk_core.timekeeper.offs_boot,
        [TK_OFFS_TAI]   = &tk_core.timekeeper.offs_tai,
 };
 
@@ -860,39 +886,6 @@ void ktime_get_ts64(struct timespec64 *ts)
 }
 EXPORT_SYMBOL_GPL(ktime_get_ts64);
 
-/**
- * ktime_get_active_ts64 - Get the active non-suspended monotonic clock
- * @ts:                pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime clock and
- * the wall_to_monotonic offset, subtracts the accumulated suspend time and
- * stores the result in normalized timespec64 format in the variable
- * pointed to by @ts.
- */
-void ktime_get_active_ts64(struct timespec64 *ts)
-{
-       struct timekeeper *tk = &tk_core.timekeeper;
-       struct timespec64 tomono, tsusp;
-       u64 nsec, nssusp;
-       unsigned int seq;
-
-       WARN_ON(timekeeping_suspended);
-
-       do {
-               seq = read_seqcount_begin(&tk_core.seq);
-               ts->tv_sec = tk->xtime_sec;
-               nsec = timekeeping_get_ns(&tk->tkr_mono);
-               tomono = tk->wall_to_monotonic;
-               nssusp = tk->time_suspended;
-       } while (read_seqcount_retry(&tk_core.seq, seq));
-
-       ts->tv_sec += tomono.tv_sec;
-       ts->tv_nsec = 0;
-       timespec64_add_ns(ts, nsec + tomono.tv_nsec);
-       tsusp = ns_to_timespec64(nssusp);
-       *ts = timespec64_sub(*ts, tsusp);
-}
-
 /**
  * ktime_get_seconds - Get the seconds portion of CLOCK_MONOTONIC
  *
@@ -1593,6 +1586,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
                return;
        }
        tk_xtime_add(tk, delta);
+       tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, *delta));
        tk_update_sleep_time(tk, timespec64_to_ktime(*delta));
        tk_debug_account_sleep_time(delta);
 }
@@ -2125,7 +2119,7 @@ void update_wall_time(void)
 void getboottime64(struct timespec64 *ts)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
-       ktime_t t = ktime_sub(tk->offs_real, tk->time_suspended);
+       ktime_t t = ktime_sub(tk->offs_real, tk->offs_boot);
 
        *ts = ktime_to_timespec64(t);
 }
@@ -2188,6 +2182,7 @@ void do_timer(unsigned long ticks)
  * ktime_get_update_offsets_now - hrtimer helper
  * @cwsseq:    pointer to check and store the clock was set sequence number
  * @offs_real: pointer to storage for monotonic -> realtime offset
+ * @offs_boot: pointer to storage for monotonic -> boottime offset
  * @offs_tai:  pointer to storage for monotonic -> clock tai offset
  *
  * Returns current monotonic time and updates the offsets if the
@@ -2197,7 +2192,7 @@ void do_timer(unsigned long ticks)
  * Called from hrtimer_interrupt() or retrigger_next_event()
  */
 ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
-                                    ktime_t *offs_tai)
+                                    ktime_t *offs_boot, ktime_t *offs_tai)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
        unsigned int seq;
@@ -2214,6 +2209,7 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
                if (*cwsseq != tk->clock_was_set_seq) {
                        *cwsseq = tk->clock_was_set_seq;
                        *offs_real = tk->offs_real;
+                       *offs_boot = tk->offs_boot;
                        *offs_tai = tk->offs_tai;
                }
 
index 79b67f5e0343caf35cf15c3cd99b905d29a31a10..7a9b4eb7a1d5bde85e7a7b1c7747602cdd605975 100644 (file)
@@ -6,6 +6,7 @@
  */
 extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq,
                                            ktime_t *offs_real,
+                                           ktime_t *offs_boot,
                                            ktime_t *offs_tai);
 
 extern int timekeeping_valid_for_hres(void);
index dfbcf9ee1447645594b06736e2ca9616e6cd93eb..414d7210b2eca7ccb78ac1748a31aefb99414007 100644 (file)
@@ -1165,7 +1165,7 @@ static struct {
        { trace_clock,                  "perf",         1 },
        { ktime_get_mono_fast_ns,       "mono",         1 },
        { ktime_get_raw_fast_ns,        "mono_raw",     1 },
-       { ktime_get_mono_fast_ns,       "boot",         1 },
+       { ktime_get_boot_fast_ns,       "boot",         1 },
        ARCH_TRACE_CLOCKS
 };
 
index e1d1f290bf354540c9148863c931c3f1d38278cf..18989b5b3b56b8b0b59836492606ec99fd3debbe 100644 (file)
@@ -233,13 +233,12 @@ static int kobject_add_internal(struct kobject *kobj)
 
                /* be noisy on error issues */
                if (error == -EEXIST)
-                       WARN(1,
-                            "%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
-                            __func__, kobject_name(kobj));
+                       pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
+                              __func__, kobject_name(kobj));
                else
-                       WARN(1, "%s failed for %s (error: %d parent: %s)\n",
-                            __func__, kobject_name(kobj), error,
-                            parent ? kobject_name(parent) : "'none'");
+                       pr_err("%s failed for %s (error: %d parent: %s)\n",
+                              __func__, kobject_name(kobj), error,
+                              parent ? kobject_name(parent) : "'none'");
        } else
                kobj->state_in_sysfs = 1;
 
index 188f195883b90b40d8371e8e04ff5acd4d9d1526..9d5968d1e8e3360ecd1dd9a095139090a1a1f107 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -100,11 +100,20 @@ pgprot_t protection_map[16] __ro_after_init = {
        __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+#ifndef CONFIG_ARCH_HAS_FILTER_PGPROT
+static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+{
+       return prot;
+}
+#endif
+
 pgprot_t vm_get_page_prot(unsigned long vm_flags)
 {
-       return __pgprot(pgprot_val(protection_map[vm_flags &
+       pgprot_t ret = __pgprot(pgprot_val(protection_map[vm_flags &
                                (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
                        pgprot_val(arch_vm_get_page_prot(vm_flags)));
+
+       return arch_filter_pgprot(ret);
 }
 EXPORT_SYMBOL(vm_get_page_prot);
 
index fcb40c12b1f838e24b2f2a1a58b632522acab8b4..3b3d33ea9ed830373c08889f3e38d7bc695f313b 100644 (file)
@@ -2569,6 +2569,11 @@ static int try_write(struct ceph_connection *con)
        int ret = 1;
 
        dout("try_write start %p state %lu\n", con, con->state);
+       if (con->state != CON_STATE_PREOPEN &&
+           con->state != CON_STATE_CONNECTING &&
+           con->state != CON_STATE_NEGOTIATING &&
+           con->state != CON_STATE_OPEN)
+               return 0;
 
 more:
        dout("try_write out_kvec_bytes %d\n", con->out_kvec_bytes);
@@ -2594,6 +2599,8 @@ static int try_write(struct ceph_connection *con)
        }
 
 more_kvec:
+       BUG_ON(!con->sock);
+
        /* kvec data queued? */
        if (con->out_kvec_left) {
                ret = write_partial_kvec(con);
index b3dac24412d34cbe2e3616371db9fe9838ce550f..21ac6e3b96bba0f34625d4e8c92afd61042f7c87 100644 (file)
@@ -209,6 +209,14 @@ static void reopen_session(struct ceph_mon_client *monc)
        __open_session(monc);
 }
 
+static void un_backoff(struct ceph_mon_client *monc)
+{
+       monc->hunt_mult /= 2; /* reduce by 50% */
+       if (monc->hunt_mult < 1)
+               monc->hunt_mult = 1;
+       dout("%s hunt_mult now %d\n", __func__, monc->hunt_mult);
+}
+
 /*
  * Reschedule delayed work timer.
  */
@@ -963,6 +971,7 @@ static void delayed_work(struct work_struct *work)
                if (!monc->hunting) {
                        ceph_con_keepalive(&monc->con);
                        __validate_auth(monc);
+                       un_backoff(monc);
                }
 
                if (is_auth &&
@@ -1123,9 +1132,8 @@ static void finish_hunting(struct ceph_mon_client *monc)
                dout("%s found mon%d\n", __func__, monc->cur_mon);
                monc->hunting = false;
                monc->had_a_connection = true;
-               monc->hunt_mult /= 2; /* reduce by 50% */
-               if (monc->hunt_mult < 1)
-                       monc->hunt_mult = 1;
+               un_backoff(monc);
+               __schedule_delayed(monc);
        }
 }
 
index 69734b0eafd0d6941cc1a232d219e5d9705a0c42..9aa15bfc79369aebf6eaa0ef8dd32acecd7a1ec5 100644 (file)
@@ -1492,7 +1492,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
                              int op_flag)
 {
        struct snd_ctl_tlv header;
-       unsigned int *container;
+       unsigned int __user *container;
        unsigned int container_size;
        struct snd_kcontrol *kctl;
        struct snd_ctl_elem_id id;
index b719d0bd833ecb6d7560380db5eb3b78a9b040c4..06d7c40af570c05fc20e0d13e1ded5c5ff36823b 100644 (file)
@@ -27,10 +27,11 @@ static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
                                      s32 __user *src)
 {
        snd_pcm_sframes_t delay;
+       int err;
 
-       delay = snd_pcm_delay(substream);
-       if (delay < 0)
-               return delay;
+       err = snd_pcm_delay(substream, &delay);
+       if (err)
+               return err;
        if (put_user(delay, src))
                return -EFAULT;
        return 0;
index 35ffccea94c3eb6cfe7755b6c1da7547d018a9a0..0e875d5a9e8621ee378014176596207d201a2363 100644 (file)
@@ -2692,7 +2692,8 @@ static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
        return err;
 }
                
-static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
+static int snd_pcm_delay(struct snd_pcm_substream *substream,
+                        snd_pcm_sframes_t *delay)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
@@ -2708,7 +2709,9 @@ static snd_pcm_sframes_t snd_pcm_delay(struct snd_pcm_substream *substream)
                n += runtime->delay;
        }
        snd_pcm_stream_unlock_irq(substream);
-       return err < 0 ? err : n;
+       if (!err)
+               *delay = n;
+       return err;
 }
                
 static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
@@ -2751,6 +2754,7 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
        sync_ptr.s.status.hw_ptr = status->hw_ptr;
        sync_ptr.s.status.tstamp = status->tstamp;
        sync_ptr.s.status.suspended_state = status->suspended_state;
+       sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
        snd_pcm_stream_unlock_irq(substream);
        if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
                return -EFAULT;
@@ -2916,11 +2920,13 @@ static int snd_pcm_common_ioctl(struct file *file,
                return snd_pcm_hwsync(substream);
        case SNDRV_PCM_IOCTL_DELAY:
        {
-               snd_pcm_sframes_t delay = snd_pcm_delay(substream);
+               snd_pcm_sframes_t delay;
                snd_pcm_sframes_t __user *res = arg;
+               int err;
 
-               if (delay < 0)
-                       return delay;
+               err = snd_pcm_delay(substream, &delay);
+               if (err)
+                       return err;
                if (put_user(delay, res))
                        return -EFAULT;
                return 0;
@@ -3008,13 +3014,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
        case SNDRV_PCM_IOCTL_DROP:
                return snd_pcm_drop(substream);
        case SNDRV_PCM_IOCTL_DELAY:
-       {
-               result = snd_pcm_delay(substream);
-               if (result < 0)
-                       return result;
-               *frames = result;
-               return 0;
-       }
+               return snd_pcm_delay(substream, frames);
        default:
                return -EINVAL;
        }
@@ -3234,7 +3234,7 @@ static __poll_t snd_pcm_capture_poll(struct file *file, poll_table * wait)
 /*
  * mmap status record
  */
-static int snd_pcm_mmap_status_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_status_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
@@ -3270,7 +3270,7 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
 /*
  * mmap control record
  */
-static int snd_pcm_mmap_control_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_control_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
@@ -3359,7 +3359,7 @@ snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
 /*
  * fault callback for mmapping a RAM page
  */
-static int snd_pcm_mmap_data_fault(struct vm_fault *vmf)
+static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
 {
        struct snd_pcm_substream *substream = vmf->vma->vm_private_data;
        struct snd_pcm_runtime *runtime;
index c3908862bc8b63932aaa8724a50d7a5ae19a8cf3..86ca584c27b28081663e8493e7b54b5d0009784d 100644 (file)
@@ -26,6 +26,7 @@
 #include <sound/seq_oss_legacy.h>
 #include "seq_oss_readq.h"
 #include "seq_oss_writeq.h"
+#include <linux/nospec.h>
 
 
 /*
@@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
 {
        struct seq_oss_synthinfo *info;
 
-       if (!snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
                        return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
                }
 
+               ch = array_index_nospec(ch, info->nr_voices);
                if (note == 255 && info->ch[ch].note >= 0) {
                        /* volume control */
                        int type;
@@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
 {
        struct seq_oss_synthinfo *info;
 
-       if (!snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
                        return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
                }
 
+               ch = array_index_nospec(ch, info->nr_voices);
                if (info->ch[ch].note >= 0) {
                        note = info->ch[ch].note;
                        info->ch[ch].vel = 0;
@@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, s
 static int
 set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       if (!snd_seq_oss_synth_info(dp, dev))
                return -ENXIO;
        
        ev->type = type;
@@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note,
 static int
 set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       if (!snd_seq_oss_synth_info(dp, dev))
                return -ENXIO;
        
        ev->type = type;
index b30b2139e3f033fd71e59fbe10cfa1e25340adc6..9debd1b8fd2880fde1e0fe349a4745bdb443b477 100644 (file)
@@ -29,6 +29,7 @@
 #include "../seq_lock.h"
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 
 /*
@@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp, int dev)
 {
        if (dev < 0 || dev >= dp->max_mididev)
                return NULL;
+       dev = array_index_nospec(dev, dp->max_mididev);
        return get_mdev(dev);
 }
 
index cd0e0ebbfdb1a1931b50f0fc9d70cdd08c17f740..278ebb9931225998dd07f0606eeabe289d71aff5 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/nospec.h>
 
 /*
  * constants
@@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
        dp->max_synthdev = 0;
 }
 
-/*
- * check if the specified device is MIDI mapped device
- */
-static int
-is_midi_dev(struct seq_oss_devinfo *dp, int dev)
+static struct seq_oss_synthinfo *
+get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
 {
        if (dev < 0 || dev >= dp->max_synthdev)
-               return 0;
-       if (dp->synths[dev].is_midi)
-               return 1;
-       return 0;
+               return NULL;
+       dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
+       return &dp->synths[dev];
 }
 
 /*
@@ -359,14 +356,20 @@ static struct seq_oss_synth *
 get_synthdev(struct seq_oss_devinfo *dp, int dev)
 {
        struct seq_oss_synth *rec;
-       if (dev < 0 || dev >= dp->max_synthdev)
-               return NULL;
-       if (! dp->synths[dev].opened)
+       struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
+
+       if (!info)
                return NULL;
-       if (dp->synths[dev].is_midi)
-               return &midi_synth_dev;
-       if ((rec = get_sdev(dev)) == NULL)
+       if (!info->opened)
                return NULL;
+       if (info->is_midi) {
+               rec = &midi_synth_dev;
+               snd_use_lock_use(&rec->use_lock);
+       } else {
+               rec = get_sdev(dev);
+               if (!rec)
+                       return NULL;
+       }
        if (! rec->opened) {
                snd_use_lock_free(&rec->use_lock);
                return NULL;
@@ -402,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
        struct seq_oss_synth *rec;
        struct seq_oss_synthinfo *info;
 
-       if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
-               return;
-       info = &dp->synths[dev];
-       if (! info->opened)
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info || !info->opened)
                return;
        if (info->sysex)
                info->sysex->len = 0; /* reset sysex */
@@ -454,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
                            const char __user *buf, int p, int c)
 {
        struct seq_oss_synth *rec;
+       struct seq_oss_synthinfo *info;
        int rc;
 
-       if (dev < 0 || dev >= dp->max_synthdev)
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       if (is_midi_dev(dp, dev))
+       if (info->is_midi)
                return 0;
        if ((rec = get_synthdev(dp, dev)) == NULL)
                return -ENXIO;
@@ -467,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
        if (rec->oper.load_patch == NULL)
                rc = -ENXIO;
        else
-               rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
+               rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
        snd_use_lock_free(&rec->use_lock);
        return rc;
 }
 
 /*
- * check if the device is valid synth device
+ * check if the device is valid synth device and return the synth info
  */
-int
-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
+struct seq_oss_synthinfo *
+snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
 {
        struct seq_oss_synth *rec;
+
        rec = get_synthdev(dp, dev);
        if (rec) {
                snd_use_lock_free(&rec->use_lock);
-               return 1;
+               return get_synthinfo_nospec(dp, dev);
        }
-       return 0;
+       return NULL;
 }
 
 
@@ -499,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
        int i, send;
        unsigned char *dest;
        struct seq_oss_synth_sysex *sysex;
+       struct seq_oss_synthinfo *info;
 
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info)
                return -ENXIO;
 
-       sysex = dp->synths[dev].sysex;
+       sysex = info->sysex;
        if (sysex == NULL) {
                sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
                if (sysex == NULL)
                        return -ENOMEM;
-               dp->synths[dev].sysex = sysex;
+               info->sysex = sysex;
        }
 
        send = 0;
@@ -553,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
 int
 snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev))
+       struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
+
+       if (!info)
                return -EINVAL;
-       snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
-                             dp->synths[dev].arg.addr.port);
+       snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
+                             info->arg.addr.port);
        return 0;
 }
 
@@ -568,16 +576,18 @@ int
 snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
 {
        struct seq_oss_synth *rec;
+       struct seq_oss_synthinfo *info;
        int rc;
 
-       if (is_midi_dev(dp, dev))
+       info = get_synthinfo_nospec(dp, dev);
+       if (!info || info->is_midi)
                return -ENXIO;
        if ((rec = get_synthdev(dp, dev)) == NULL)
                return -ENXIO;
        if (rec->oper.ioctl == NULL)
                rc = -ENXIO;
        else
-               rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
+               rc = rec->oper.ioctl(&info->arg, cmd, addr);
        snd_use_lock_free(&rec->use_lock);
        return rc;
 }
@@ -589,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, u
 int
 snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
 {
-       if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
+       struct seq_oss_synthinfo *info;
+
+       info = snd_seq_oss_synth_info(dp, dev);
+       if (!info || info->is_midi)
                return -ENXIO;
        ev->type = SNDRV_SEQ_EVENT_OSS;
        memcpy(ev->data.raw8.d, data, 8);
index 74ac55f166b6517751d197c14a5aaf4b6805ca01..a63f9e22974dfb33ff0f309f0ab309625e0265ea 100644 (file)
@@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
 void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
 int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
                                 const char __user *buf, int p, int c);
-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
+struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
+                                                int dev);
 int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
                            struct snd_seq_event *ev);
 int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
index ddcc1a325a618124b9206a9f0c0c9a23774938ed..42920a2433282befccd62aaa43bbec949fe22e6c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <linux/slab.h>
 #include <linux/export.h>
+#include <linux/nospec.h>
 #include <sound/opl3.h>
 #include <sound/asound_fm.h>
 
@@ -448,7 +449,7 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
 {
        unsigned short reg_side;
        unsigned char op_offset;
-       unsigned char voice_offset;
+       unsigned char voice_offset, voice_op;
 
        unsigned short opl3_reg;
        unsigned char reg_val;
@@ -473,7 +474,9 @@ static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * v
                voice_offset = voice->voice - MAX_OPL2_VOICES;
        }
        /* Get register offset of operator */
-       op_offset = snd_opl3_regmap[voice_offset][voice->op];
+       voice_offset = array_index_nospec(voice_offset, MAX_OPL2_VOICES);
+       voice_op = array_index_nospec(voice->op, 4);
+       op_offset = snd_opl3_regmap[voice_offset][voice_op];
 
        reg_val = 0x00;
        /* Set amplitude modulation (tremolo) effect */
index 8573289c381ed7314c6e1a08d4b39191756941f9..928a255bfc351406058b1c2bd8a43d785f63ef97 100644 (file)
@@ -435,7 +435,7 @@ int snd_dice_stream_init_duplex(struct snd_dice *dice)
                err = init_stream(dice, AMDTP_IN_STREAM, i);
                if (err < 0) {
                        for (; i >= 0; i--)
-                               destroy_stream(dice, AMDTP_OUT_STREAM, i);
+                               destroy_stream(dice, AMDTP_IN_STREAM, i);
                        goto end;
                }
        }
index 4ddb4cdd054b860142da4356dc6abeef44b4c698..96bb01b6b7512df8aea3871e61275773d4d8543d 100644 (file)
@@ -14,7 +14,7 @@ MODULE_LICENSE("GPL v2");
 #define OUI_WEISS              0x001c6a
 #define OUI_LOUD               0x000ff2
 #define OUI_FOCUSRITE          0x00130e
-#define OUI_TCELECTRONIC       0x001486
+#define OUI_TCELECTRONIC       0x000166
 
 #define DICE_CATEGORY_ID       0x04
 #define WEISS_CATEGORY_ID      0x00
index 7eb617175fdec656f0ae6a8ad8387c416f535b39..a31a70dccecff024f92ee8bbcc9ead5ef1cd4bed 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "hpi_internal.h"
 #include "hpimsginit.h"
+#include <linux/nospec.h>
 
 /* The actual message size for each object type */
 static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
@@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
 {
        u16 size;
 
-       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
+       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+               object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
                size = msg_size[object];
-       else
+       } else {
                size = sizeof(*phm);
+       }
 
        memset(phm, 0, size);
        phm->size = size;
@@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
 {
        u16 size;
 
-       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
+       if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
+               object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
                size = res_size[object];
-       else
+       } else {
                size = sizeof(*phr);
+       }
 
        memset(phr, 0, sizeof(*phr));
        phr->size = size;
index 5badd08e1d69cc12657410359255ab691eff62f0..b1a2a7ea4172331c07b50340c5d26ebe2f9e6bf0 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/stringify.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
+#include <linux/nospec.h>
 
 #ifdef MODULE_FIRMWARE
 MODULE_FIRMWARE("asihpi/dsp5000.bin");
@@ -186,7 +187,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct hpi_adapter *pa = NULL;
 
                if (hm->h.adapter_index < ARRAY_SIZE(adapters))
-                       pa = &adapters[hm->h.adapter_index];
+                       pa = &adapters[array_index_nospec(hm->h.adapter_index,
+                                                         ARRAY_SIZE(adapters))];
 
                if (!pa || !pa->adapter || !pa->adapter->type) {
                        hpi_init_response(&hr->r0, hm->h.object,
index 57df06e76968ac4abd0f00b3005c416af256cb7b..cc009a4a3d1d206a8480a506894a59c0226c2e9a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/compat.h>
+#include <linux/nospec.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
@@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_codec *codec,
        
        if (get_user(verb, &arg->verb))
                return -EFAULT;
-       res = get_wcaps(codec, verb >> 24);
+       /* open-code get_wcaps(verb>>24) with nospec */
+       verb >>= 24;
+       if (verb < codec->core.start_nid ||
+           verb >= codec->core.start_nid + codec->core.num_nodes) {
+               res = 0;
+       } else {
+               verb -= codec->core.start_nid;
+               verb = array_index_nospec(verb, codec->core.num_nodes);
+               res = codec->wcaps[verb];
+       }
        if (put_user(res, &arg->res))
                return -EFAULT;
        return 0;
index b4f1b6e88305496f91d028ceb82fe9b8a6a60ccb..7d7eb1354eeec4dc48a734251e6cb9f5d12cd850 100644 (file)
@@ -1383,6 +1383,8 @@ static void hdmi_pcm_setup_pin(struct hdmi_spec *spec,
                pcm = get_pcm_rec(spec, per_pin->pcm_idx);
        else
                return;
+       if (!pcm->pcm)
+               return;
        if (!test_bit(per_pin->pcm_idx, &spec->pcm_in_use))
                return;
 
@@ -2151,8 +2153,13 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
        int dev, err;
        int pin_idx, pcm_idx;
 
-
        for (pcm_idx = 0; pcm_idx < spec->pcm_used; pcm_idx++) {
+               if (!get_pcm_rec(spec, pcm_idx)->pcm) {
+                       /* no PCM: mark this for skipping permanently */
+                       set_bit(pcm_idx, &spec->pcm_bitmap);
+                       continue;
+               }
+
                err = generic_hdmi_build_jack(codec, pcm_idx);
                if (err < 0)
                        return err;
index fc77bf7a1544fa5c5ac9d1da2b74328436c8226e..8c238e51bb5abad3a874bffc4d7e718feb3cb6cd 100644 (file)
@@ -331,6 +331,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
                /* fallthrough */
        case 0x10ec0215:
        case 0x10ec0233:
+       case 0x10ec0235:
        case 0x10ec0236:
        case 0x10ec0255:
        case 0x10ec0256:
@@ -6575,6 +6576,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+       SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
@@ -7160,8 +7162,11 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0298:
                spec->codec_variant = ALC269_TYPE_ALC298;
                break;
+       case 0x10ec0235:
        case 0x10ec0255:
                spec->codec_variant = ALC269_TYPE_ALC255;
+               spec->shutup = alc256_shutup;
+               spec->init_hook = alc256_init;
                break;
        case 0x10ec0236:
        case 0x10ec0256:
index 4c59983158e0ed8d37bcad8ae3735129a1bd1ef8..11b5b5e0e0580fd3a3d33cf99dd71728db1bdd3a 100644 (file)
 #include <linux/pci.h>
 #include <linux/math64.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -5698,40 +5699,43 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
                struct snd_pcm_channel_info *info)
 {
        struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+       unsigned int channel = info->channel;
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
+               if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: output channel out of range (%d)\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               if (hdspm->channel_map_out[info->channel] < 0) {
+               channel = array_index_nospec(channel, hdspm->max_channels_out);
+               if (hdspm->channel_map_out[channel] < 0) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: output channel %d mapped out\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               info->offset = hdspm->channel_map_out[info->channel] *
+               info->offset = hdspm->channel_map_out[channel] *
                        HDSPM_CHANNEL_BUFFER_BYTES;
        } else {
-               if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
+               if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: input channel out of range (%d)\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               if (hdspm->channel_map_in[info->channel] < 0) {
+               channel = array_index_nospec(channel, hdspm->max_channels_in);
+               if (hdspm->channel_map_in[channel] < 0) {
                        dev_info(hdspm->card->dev,
                                 "snd_hdspm_channel_info: input channel %d mapped out\n",
-                                info->channel);
+                                channel);
                        return -EINVAL;
                }
 
-               info->offset = hdspm->channel_map_in[info->channel] *
+               info->offset = hdspm->channel_map_in[channel] *
                        HDSPM_CHANNEL_BUFFER_BYTES;
        }
 
index df648b1d92177c30c2380b96de4e9ebd24fb07aa..edd765e2237707ea468455723d542eb74e97bf0f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/nospec.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -2071,9 +2072,10 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
        if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
                return -EINVAL;
 
-       if ((chn = rme9652->channel_map[info->channel]) < 0) {
+       chn = rme9652->channel_map[array_index_nospec(info->channel,
+                                                     RME9652_NCHANNELS)];
+       if (chn < 0)
                return -EINVAL;
-       }
 
        info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
        info->first = 0;
index b205c782e494133d05fd27cb76509e7e690d5f85..f41560ecbcd18024f2f1354cd741115fcbd69739 100644 (file)
@@ -43,7 +43,7 @@
 #define DUAL_CHANNEL           2
 
 static struct snd_soc_jack cz_jack;
-struct clk *da7219_dai_clk;
+static struct clk *da7219_dai_clk;
 
 static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
index 80c2a06285bbe1f5df619542836bef3a15941c96..12bf24c26818a3ff046a426f56d0cebb356be9a2 100644 (file)
@@ -502,7 +502,7 @@ static int adau17x1_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (adau->sigmadsp) {
-               ret = adau17x1_setup_firmware(adau, params_rate(params));
+               ret = adau17x1_setup_firmware(component, params_rate(params));
                if (ret < 0)
                        return ret;
        }
@@ -835,26 +835,40 @@ bool adau17x1_volatile_register(struct device *dev, unsigned int reg)
 }
 EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
 
-int adau17x1_setup_firmware(struct adau *adau, unsigned int rate)
+int adau17x1_setup_firmware(struct snd_soc_component *component,
+       unsigned int rate)
 {
        int ret;
-       int dspsr;
+       int dspsr, dsp_run;
+       struct adau *adau = snd_soc_component_get_drvdata(component);
+       struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
+
+       snd_soc_dapm_mutex_lock(dapm);
 
        ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);
        if (ret)
-               return ret;
+               goto err;
+
+       ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run);
+       if (ret)
+               goto err;
 
        regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);
        regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);
+       regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0);
 
        ret = sigmadsp_setup(adau->sigmadsp, rate);
        if (ret) {
                regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);
-               return ret;
+               goto err;
        }
        regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);
+       regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run);
 
-       return 0;
+err:
+       snd_soc_dapm_mutex_unlock(dapm);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
 
index a7b1cb770814624f51465664e2dd3e592a91f1df..e6fe87beec07701810be444eee2abd3280c51674 100644 (file)
@@ -68,7 +68,8 @@ int adau17x1_resume(struct snd_soc_component *component);
 
 extern const struct snd_soc_dai_ops adau17x1_dai_ops;
 
-int adau17x1_setup_firmware(struct adau *adau, unsigned int rate);
+int adau17x1_setup_firmware(struct snd_soc_component *component,
+       unsigned int rate);
 bool adau17x1_has_dsp(struct adau *adau);
 
 #define ADAU17X1_CLOCK_CONTROL                 0x4000
index 12ee83d52405d06a72c8cd5a67485c69bf2ddeb1..b7cf7cce95fecd526bd4d8699e6dee9f4119d4db 100644 (file)
@@ -1187,7 +1187,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                return irq;
        }
 
-       ret = devm_request_irq(dev, irq, pm8916_mbhc_switch_irq_handler,
+       ret = devm_request_threaded_irq(dev, irq, NULL,
+                              pm8916_mbhc_switch_irq_handler,
                               IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
                               IRQF_ONESHOT,
                               "mbhc switch irq", priv);
@@ -1201,7 +1202,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                        return irq;
                }
 
-               ret = devm_request_irq(dev, irq, mbhc_btn_press_irq_handler,
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                                      mbhc_btn_press_irq_handler,
                                       IRQF_TRIGGER_RISING |
                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                       "mbhc btn press irq", priv);
@@ -1214,7 +1216,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
                        return irq;
                }
 
-               ret = devm_request_irq(dev, irq, mbhc_btn_release_irq_handler,
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                                      mbhc_btn_release_irq_handler,
                                       IRQF_TRIGGER_RISING |
                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
                                       "mbhc btn release irq", priv);
index e8a66b03faabf405ec43f7170e0205fd4650eb29..1570b91bf018f9421c91a4c66631d819a800876c 100644 (file)
@@ -89,6 +89,7 @@ static const struct reg_default rt5514_reg[] = {
        {RT5514_PLL3_CALIB_CTRL5,       0x40220012},
        {RT5514_DELAY_BUF_CTRL1,        0x7fff006a},
        {RT5514_DELAY_BUF_CTRL3,        0x00000000},
+       {RT5514_ASRC_IN_CTRL1,          0x00000003},
        {RT5514_DOWNFILTER0_CTRL1,      0x00020c2f},
        {RT5514_DOWNFILTER0_CTRL2,      0x00020c2f},
        {RT5514_DOWNFILTER0_CTRL3,      0x10000362},
@@ -181,6 +182,7 @@ static bool rt5514_readable_register(struct device *dev, unsigned int reg)
        case RT5514_PLL3_CALIB_CTRL5:
        case RT5514_DELAY_BUF_CTRL1:
        case RT5514_DELAY_BUF_CTRL3:
+       case RT5514_ASRC_IN_CTRL1:
        case RT5514_DOWNFILTER0_CTRL1:
        case RT5514_DOWNFILTER0_CTRL2:
        case RT5514_DOWNFILTER0_CTRL3:
@@ -238,6 +240,7 @@ static bool rt5514_i2c_readable_register(struct device *dev,
        case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5:
        case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3:
+       case RT5514_DSP_MAPPING | RT5514_ASRC_IN_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2:
        case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3:
index 40a700493f4c8f0d3dec67956ee8afb8b20c37f3..da8fd98c7f51c2a1ee3116a00d17d8820bb3582d 100644 (file)
@@ -144,6 +144,13 @@ static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
 
        psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
 
+       /* Do not loop-search if PM (1 ~ 256) alone can serve the ratio */
+       if (ratio <= 256) {
+               pm = ratio;
+               fp = 1;
+               goto out;
+       }
+
        /* Set the max fluctuation -- 0.1% of the max devisor */
        savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
 
index 0823b08923b5ef5d0860c14807af75f899eed0ed..89df2d9f63d7d45d219d7172bcb85e9926e8e549 100644 (file)
@@ -217,6 +217,7 @@ struct fsl_ssi_soc_data {
  * @dai_fmt: DAI configuration this device is currently used with
  * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
  * @i2s_net: I2S and Network mode configurations of SCR register
+ *           (this is the initial settings based on the DAI format)
  * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
  * @use_dma: DMA is used or FIQ with stream filter
  * @use_dual_fifo: DMA with support for dual FIFO mode
@@ -829,16 +830,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (!fsl_ssi_is_ac97(ssi)) {
+               /*
+                * Keep the ssi->i2s_net intact while having a local variable
+                * to override settings for special use cases. Otherwise, the
+                * ssi->i2s_net will lose the settings for regular use cases.
+                */
+               u8 i2s_net = ssi->i2s_net;
+
                /* Normal + Network mode to send 16-bit data in 32-bit frames */
                if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
-                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
+                       i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
 
                /* Use Normal mode to send mono data at 1st slot of 2 slots */
                if (channels == 1)
-                       ssi->i2s_net = SSI_SCR_I2S_MODE_NORMAL;
+                       i2s_net = SSI_SCR_I2S_MODE_NORMAL;
 
                regmap_update_bits(regs, REG_SSI_SCR,
-                                  SSI_SCR_I2S_NET_MASK, ssi->i2s_net);
+                                  SSI_SCR_I2S_NET_MASK, i2s_net);
        }
 
        /* In synchronous mode, the SSI uses STCCR for capture */
index ceb105cbd461582196bff4e59c225cf6083952bd..addac2a8e52a573d40e5a7a0ede942c2fa85f6ab 100644 (file)
@@ -72,24 +72,28 @@ config SND_SOC_INTEL_BAYTRAIL
          for Baytrail Chromebooks but this option is now deprecated and is
          not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
 
+config SND_SST_ATOM_HIFI2_PLATFORM
+       tristate
+       select SND_SOC_COMPRESS
+
 config SND_SST_ATOM_HIFI2_PLATFORM_PCI
-       tristate "PCI HiFi2 (Medfield, Merrifield) Platforms"
+       tristate "PCI HiFi2 (Merrifield) Platforms"
        depends on X86 && PCI
        select SND_SST_IPC_PCI
-       select SND_SOC_COMPRESS
+       select SND_SST_ATOM_HIFI2_PLATFORM
        help
-         If you have a Intel Medfield or Merrifield/Edison platform, then
+         If you have a Intel Merrifield/Edison platform, then
          enable this option by saying Y or m. Distros will typically not
-         enable this option: Medfield devices are not available to
-         developers and while Merrifield/Edison can run a mainline kernel with
-         limited functionality it will require a firmware file which
-         is not in the standard firmware tree
+         enable this option: while Merrifield/Edison can run a mainline
+         kernel with limited functionality it will require a firmware file
+         which is not in the standard firmware tree
 
-config SND_SST_ATOM_HIFI2_PLATFORM
+config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
        tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms"
+       default ACPI
        depends on X86 && ACPI
        select SND_SST_IPC_ACPI
-       select SND_SOC_COMPRESS
+       select SND_SST_ATOM_HIFI2_PLATFORM
        select SND_SOC_ACPI_INTEL_MATCH
        select IOSF_MBI
        help
index 09db2aec12a3010525b872ec817626cb5365b311..b2f5d2fa354d1d888dddf829847883bc84bdcdd1 100644 (file)
@@ -281,7 +281,7 @@ static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream,
 static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
                                 unsigned int freq)
 {
-       struct clk *parent_clk;
+       struct clk *parent_clk, *mux;
        char *parent_clk_name;
        int ret = 0;
 
@@ -329,14 +329,21 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
                return -ENODEV;
        }
 
+       mux = clk_get_parent(dmic->fclk);
+       if (IS_ERR(mux)) {
+               dev_err(dmic->dev, "can't get fck mux parent\n");
+               clk_put(parent_clk);
+               return -ENODEV;
+       }
+
        mutex_lock(&dmic->mutex);
        if (dmic->active) {
                /* disable clock while reparenting */
                pm_runtime_put_sync(dmic->dev);
-               ret = clk_set_parent(dmic->fclk, parent_clk);
+               ret = clk_set_parent(mux, parent_clk);
                pm_runtime_get_sync(dmic->dev);
        } else {
-               ret = clk_set_parent(dmic->fclk, parent_clk);
+               ret = clk_set_parent(mux, parent_clk);
        }
        mutex_unlock(&dmic->mutex);
 
@@ -349,6 +356,7 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
        dmic->fclk_freq = freq;
 
 err_busy:
+       clk_put(mux);
        clk_put(parent_clk);
 
        return ret;
index 6a76688a8ba953d5b8f373e6a382c8437ec7bfa6..94f081b93258f8948035cee1b816feef3ea79a68 100644 (file)
@@ -1536,7 +1536,7 @@ static int rsnd_remove(struct platform_device *pdev)
        return ret;
 }
 
-static int rsnd_suspend(struct device *dev)
+static int __maybe_unused rsnd_suspend(struct device *dev)
 {
        struct rsnd_priv *priv = dev_get_drvdata(dev);
 
@@ -1545,7 +1545,7 @@ static int rsnd_suspend(struct device *dev)
        return 0;
 }
 
-static int rsnd_resume(struct device *dev)
+static int __maybe_unused rsnd_resume(struct device *dev)
 {
        struct rsnd_priv *priv = dev_get_drvdata(dev);
 
index fa27d0fca6dce10ed8befc8df9cdf7406dbcac75..986b8b2f90fba577cce10462e75ad9966258b49f 100644 (file)
@@ -513,7 +513,7 @@ static void remove_widget(struct snd_soc_component *comp,
         */
        if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) {
                /* enumerated widget mixer */
-               for (i = 0; i < w->num_kcontrols; i++) {
+               for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
                        struct snd_kcontrol *kcontrol = w->kcontrols[i];
                        struct soc_enum *se =
                                (struct soc_enum *)kcontrol->private_value;
@@ -530,7 +530,7 @@ static void remove_widget(struct snd_soc_component *comp,
                }
        } else {
                /* volume mixer or bytes controls */
-               for (i = 0; i < w->num_kcontrols; i++) {
+               for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) {
                        struct snd_kcontrol *kcontrol = w->kcontrols[i];
 
                        if (dobj->widget.kcontrol_type
@@ -1325,8 +1325,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_denum_create(
                        ec->hdr.name);
 
                kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
-               if (kc[i].name == NULL)
+               if (kc[i].name == NULL) {
+                       kfree(se);
                        goto err_se;
+               }
                kc[i].private_value = (long)se;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = ec->hdr.access;
@@ -1442,8 +1444,10 @@ static struct snd_kcontrol_new *soc_tplg_dapm_widget_dbytes_create(
                        be->hdr.name, be->hdr.access);
 
                kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
-               if (kc[i].name == NULL)
+               if (kc[i].name == NULL) {
+                       kfree(sbe);
                        goto err;
+               }
                kc[i].private_value = (long)sbe;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = be->hdr.access;
@@ -2576,7 +2580,7 @@ int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index)
 
                        /* match index */
                        if (dobj->index != index &&
-                               dobj->index != SND_SOC_TPLG_INDEX_ALL)
+                               index != SND_SOC_TPLG_INDEX_ALL)
                                continue;
 
                        switch (dobj->type) {
index 301ad61ed4267f28476af340325ae5173a12d2ad..344d7b069d5994ff242a9f0a3f9bf19f4201ffaa 100644 (file)
@@ -1776,7 +1776,8 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
                                build_feature_ctl(state, _ftr, ch_bits, control,
                                                  &iterm, unitid, ch_read_only);
                        if (uac_v2v3_control_is_readable(master_bits, control))
-                               build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
+                               build_feature_ctl(state, _ftr, 0, control,
+                                                 &iterm, unitid,
                                                  !uac_v2v3_control_is_writeable(master_bits,
                                                                                 control));
                }
@@ -1859,7 +1860,7 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,
        check_input_term(state, d->bTerminalID, &iterm);
        if (state->mixer->protocol == UAC_VERSION_2) {
                /* Check for jack detection. */
-               if (uac_v2v3_control_is_readable(d->bmControls,
+               if (uac_v2v3_control_is_readable(le16_to_cpu(d->bmControls),
                                                 UAC2_TE_CONNECTOR)) {
                        build_connector_control(state, &iterm, true);
                }
@@ -2561,7 +2562,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
                        if (err < 0 && err != -EINVAL)
                                return err;
 
-                       if (uac_v2v3_control_is_readable(desc->bmControls,
+                       if (uac_v2v3_control_is_readable(le16_to_cpu(desc->bmControls),
                                                         UAC2_TE_CONNECTOR)) {
                                build_connector_control(&state, &state.oterm,
                                                        false);
index 9038b2e7df732d453993a180071a98ea3b2ff79f..eaa03acd4686bdd20e19b69502c23ca465977ade 100644 (file)
@@ -353,8 +353,11 @@ static struct usbmix_name_map bose_companion5_map[] = {
 /*
  * Dell usb dock with ALC4020 codec had a firmware problem where it got
  * screwed up when zero volume is passed; just skip it as a workaround
+ *
+ * Also the extension unit gives an access error, so skip it as well.
  */
 static const struct usbmix_name_map dell_alc4020_map[] = {
+       { 4, NULL },    /* extension unit */
        { 16, NULL },
        { 19, NULL },
        { 0 }
index 6a8f5843334e98558d09174e157c308644c736a5..956be9f7c72a44e9326bd15c3df328540747124d 100644 (file)
@@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor
                         * TODO: this conversion is not complete, update it
                         * after adding UAC3 values to asound.h
                         */
-                       switch (is->bChPurpose) {
+                       switch (is->bChRelationship) {
                        case UAC3_CH_MONO:
                                map = SNDRV_CHMAP_MONO;
                                break;
index ebcab5c5465d28dfff6b0fbebc5185b3e8f30001..8082f7b077f187453a38db038345eaa41d4c9a1e 100644 (file)
@@ -139,7 +139,7 @@ static void usb_stream_hwdep_vm_open(struct vm_area_struct *area)
        snd_printdd(KERN_DEBUG "%i\n", atomic_read(&us122l->mmap_count));
 }
 
-static int usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
+static vm_fault_t usb_stream_hwdep_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        struct page *page;
index d8bd7c99b48c91ab5a64914af75a434755922256..c1dd9a7b48df6749d8c566fc6fbac2a7fb1d630b 100644 (file)
@@ -31,7 +31,7 @@
 #include "usbusx2y.h"
 #include "usX2Yhwdep.h"
 
-static int snd_us428ctls_vm_fault(struct vm_fault *vmf)
+static vm_fault_t snd_us428ctls_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        struct page * page;
index 0d050528a4e154dd856e3120fa464ffddb179ca4..4fd9276b8e501a198443ac0db59439365fd10c89 100644 (file)
@@ -652,7 +652,7 @@ static void snd_usX2Y_hwdep_pcm_vm_close(struct vm_area_struct *area)
 }
 
 
-static int snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
+static vm_fault_t snd_usX2Y_hwdep_pcm_vm_fault(struct vm_fault *vmf)
 {
        unsigned long offset;
        void *vaddr;
index 8806ed5f3802335715efdb8e1eb2638ef34e473e..f8d2167cf3e7a2221b8688aff0f0fa55968db369 100644 (file)
@@ -28,29 +28,46 @@ OPTIONS
 <command>...::
        Any command you can specify in a shell.
 
+-i::
+--input=<file>::
+       Input file name.
+
 -f::
 --force::
        Don't do ownership validation
 
 -t::
---type=::
+--type=<type>::
        Select the memory operation type: load or store (default: load,store)
 
 -D::
---dump-raw-samples=::
+--dump-raw-samples::
        Dump the raw decoded samples on the screen in a format that is easy to parse with
        one sample per line.
 
 -x::
---field-separator::
+--field-separator=<separator>::
        Specify the field separator used when dump raw samples (-D option). By default,
        The separator is the space character.
 
 -C::
---cpu-list::
-       Restrict dump of raw samples to those provided via this option. Note that the same
-       option can be passed in record mode. It will be interpreted the same way as perf
-       record.
+--cpu=<cpu>::
+       Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a
+        comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. Default
+        is to monitor all CPUS.
+-U::
+--hide-unresolved::
+       Only display entries resolved to a symbol.
+
+-p::
+--phys-data::
+       Record/Report sample physical addresses
+
+RECORD OPTIONS
+--------------
+-e::
+--event <event>::
+       Event selector. Use 'perf mem record -e list' to list available events.
 
 -K::
 --all-kernel::
@@ -60,12 +77,12 @@ OPTIONS
 --all-user::
        Configure all used events to run in user space.
 
---ldload::
-       Specify desired latency for loads event.
+-v::
+--verbose::
+       Be more verbose (show counter open errors, etc)
 
--p::
---phys-data::
-       Record/Report sample physical addresses
+--ldlat <n>::
+       Specify desired latency for loads event.
 
 In addition, for report all perf report options are valid, and for record
 all perf record options.
index 6cb48e4cffd9a1602525510a5ea4129acd69958a..3afe8256eff275ef94c277dfae9a8c865615d681 100644 (file)
@@ -87,6 +87,7 @@ struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
        struct perf_evsel *pos;
        int diagnose = 0;
 
+       *err = 0;
        if (evlist->nr_entries == 0)
                return NULL;
 
index a4c30f1c70bec19d2175a35477e3ee3ab7bc77d3..163b92f339980e4d75208bf682607d6104c4f072 100644 (file)
@@ -146,21 +146,3 @@ char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
                zfree(&buf);
        return buf;
 }
-
-/*
- * Compare the cpuid string returned by get_cpuid() function
- * with the name generated by the jevents file read from
- * pmu-events/arch/s390/mapfile.csv.
- *
- * Parameter mapcpuid is the cpuid as stored in the
- * pmu-events/arch/s390/mapfile.csv. This is just the type number.
- * Parameter cpuid is the cpuid returned by function get_cpuid().
- */
-int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
-{
-       char *cp = strchr(cpuid, ',');
-
-       if (cp == NULL)
-               return -1;
-       return strncmp(cp + 1, mapcpuid, strlen(mapcpuid));
-}
index 147a27e8c937cdb5b81c6929f2896e97623cee28..f17dc601b0f39aaff4f5c92a27b93b0075df5741 100644 (file)
@@ -172,6 +172,7 @@ static bool                 interval_count;
 static const char              *output_name;
 static int                     output_fd;
 static int                     print_free_counters_hint;
+static int                     print_mixed_hw_group_error;
 
 struct perf_stat {
        bool                     record;
@@ -1126,6 +1127,30 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg)
                fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
 }
 
+static bool is_mixed_hw_group(struct perf_evsel *counter)
+{
+       struct perf_evlist *evlist = counter->evlist;
+       u32 pmu_type = counter->attr.type;
+       struct perf_evsel *pos;
+
+       if (counter->nr_members < 2)
+               return false;
+
+       evlist__for_each_entry(evlist, pos) {
+               /* software events can be part of any hardware group */
+               if (pos->attr.type == PERF_TYPE_SOFTWARE)
+                       continue;
+               if (pmu_type == PERF_TYPE_SOFTWARE) {
+                       pmu_type = pos->attr.type;
+                       continue;
+               }
+               if (pmu_type != pos->attr.type)
+                       return true;
+       }
+
+       return false;
+}
+
 static void printout(int id, int nr, struct perf_evsel *counter, double uval,
                     char *prefix, u64 run, u64 ena, double noise,
                     struct runtime_stat *st)
@@ -1178,8 +1203,11 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval,
                        counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
                        csv_sep);
 
-               if (counter->supported)
+               if (counter->supported) {
                        print_free_counters_hint = 1;
+                       if (is_mixed_hw_group(counter))
+                               print_mixed_hw_group_error = 1;
+               }
 
                fprintf(stat_config.output, "%-*s%s",
                        csv_output ? 0 : unit_width,
@@ -1256,7 +1284,8 @@ static void uniquify_event_name(struct perf_evsel *counter)
        char *new_name;
        char *config;
 
-       if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
+       if (counter->uniquified_name ||
+           !counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
                                           strlen(counter->pmu_name)))
                return;
 
@@ -1274,6 +1303,8 @@ static void uniquify_event_name(struct perf_evsel *counter)
                        counter->name = new_name;
                }
        }
+
+       counter->uniquified_name = true;
 }
 
 static void collect_all_aliases(struct perf_evsel *counter,
@@ -1757,6 +1788,11 @@ static void print_footer(void)
 "      echo 0 > /proc/sys/kernel/nmi_watchdog\n"
 "      perf stat ...\n"
 "      echo 1 > /proc/sys/kernel/nmi_watchdog\n");
+
+       if (print_mixed_hw_group_error)
+               fprintf(output,
+                       "The events in group usually have to be from "
+                       "the same PMU. Try reorganizing the group.\n");
 }
 
 static void print_counters(struct timespec *ts, int argc, const char **argv)
index ca7682748a4b8d34d0dd2b87eaea1e980264291d..78bcf7f8e2066e470e5868c976aaa2a1b305d207 100644 (file)
@@ -1,6 +1,6 @@
 Family-model,Version,Filename,EventType
-209[78],1,cf_z10,core
-281[78],1,cf_z196,core
-282[78],1,cf_zec12,core
-296[45],1,cf_z13,core
-3906,3,cf_z14,core
+^IBM.209[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z10,core
+^IBM.281[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z196,core
+^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core
+^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core
+^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core
index f906b793196fc7594a96f795617bdbb73ae42639..8a33ca4f9e1f7feed87159d755ba3b4797a987b6 100644 (file)
@@ -35,3 +35,6 @@ inherit=0
 # sampling disabled
 sample_freq=0
 sample_period=0
+freq=0
+write_backward=0
+sample_id_all=0
index 1ecc1f0ff84a19e771a7027419b91df728f693f5..016882dbbc16bddda77e180f421d0bcff2ad1760 100755 (executable)
@@ -19,12 +19,10 @@ trace_libc_inet_pton_backtrace() {
        expected[1]=".*inet_pton[[:space:]]\($libc\)$"
        case "$(uname -m)" in
        s390x)
-               eventattr='call-graph=dwarf'
+               eventattr='call-graph=dwarf,max-stack=4'
                expected[2]="gaih_inet.*[[:space:]]\($libc|inlined\)$"
-               expected[3]="__GI_getaddrinfo[[:space:]]\($libc|inlined\)$"
+               expected[3]="(__GI_)?getaddrinfo[[:space:]]\($libc|inlined\)$"
                expected[4]="main[[:space:]]\(.*/bin/ping.*\)$"
-               expected[5]="__libc_start_main[[:space:]]\($libc\)$"
-               expected[6]="_start[[:space:]]\(.*/bin/ping.*\)$"
                ;;
        *)
                eventattr='max-stack=3'
index 3e87486c28fe9dfd2abbcc0d53d85138730f19bd..4cd2cf93f7263e97307b69ec65d0e5c752be51fa 100644 (file)
@@ -930,8 +930,11 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
         * than leader in case leader 'leads' the sampling.
         */
        if ((leader != evsel) && leader->sample_read) {
-               attr->sample_freq   = 0;
-               attr->sample_period = 0;
+               attr->freq           = 0;
+               attr->sample_freq    = 0;
+               attr->sample_period  = 0;
+               attr->write_backward = 0;
+               attr->sample_id_all  = 0;
        }
 
        if (opts->no_samples)
@@ -1922,7 +1925,8 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
                goto fallback_missing_features;
        } else if (!perf_missing_features.group_read &&
                    evsel->attr.inherit &&
-                  (evsel->attr.read_format & PERF_FORMAT_GROUP)) {
+                  (evsel->attr.read_format & PERF_FORMAT_GROUP) &&
+                  perf_evsel__is_group_leader(evsel)) {
                perf_missing_features.group_read = true;
                pr_debug2("switching off group read\n");
                goto fallback_missing_features;
@@ -2754,8 +2758,14 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
                   (paranoid = perf_event_paranoid()) > 1) {
                const char *name = perf_evsel__name(evsel);
                char *new_name;
+               const char *sep = ":";
 
-               if (asprintf(&new_name, "%s%su", name, strchr(name, ':') ? "" : ":") < 0)
+               /* Is there already the separator in the name. */
+               if (strchr(name, '/') ||
+                   strchr(name, ':'))
+                       sep = "";
+
+               if (asprintf(&new_name, "%s%su", name, sep) < 0)
                        return false;
 
                if (evsel->name)
index d3ee3af618ef5226ec199d0c7c2df80f7726a485..92ec009a292d3efd4cf4738d51533e7e4048e22d 100644 (file)
@@ -115,6 +115,7 @@ struct perf_evsel {
        unsigned int            sample_size;
        int                     id_pos;
        int                     is_pos;
+       bool                    uniquified_name;
        bool                    snapshot;
        bool                    supported;
        bool                    needs_swap;
index 2eca8478e24f0d8b5bf60658f4190bb6213579d0..32d50492505d4b5018dc3fe3794e284e519f8346 100644 (file)
@@ -1019,13 +1019,6 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type)
        return ret;
 }
 
-static void map_groups__fixup_end(struct map_groups *mg)
-{
-       int i;
-       for (i = 0; i < MAP__NR_TYPES; ++i)
-               __map_groups__fixup_end(mg, i);
-}
-
 static char *get_kernel_version(const char *root_dir)
 {
        char version[PATH_MAX];
@@ -1233,6 +1226,7 @@ int machine__create_kernel_maps(struct machine *machine)
 {
        struct dso *kernel = machine__get_kernel(machine);
        const char *name = NULL;
+       struct map *map;
        u64 addr = 0;
        int ret;
 
@@ -1259,13 +1253,25 @@ int machine__create_kernel_maps(struct machine *machine)
                        machine__destroy_kernel_maps(machine);
                        return -1;
                }
-               machine__set_kernel_mmap(machine, addr, 0);
+
+               /* we have a real start address now, so re-order the kmaps */
+               map = machine__kernel_map(machine);
+
+               map__get(map);
+               map_groups__remove(&machine->kmaps, map);
+
+               /* assume it's the last in the kmaps */
+               machine__set_kernel_mmap(machine, addr, ~0ULL);
+
+               map_groups__insert(&machine->kmaps, map);
+               map__put(map);
        }
 
-       /*
-        * Now that we have all the maps created, just set the ->end of them:
-        */
-       map_groups__fixup_end(&machine->kmaps);
+       /* update end address of the kernel map using adjacent module address */
+       map = map__next(machine__kernel_map(machine));
+       if (map)
+               machine__set_kernel_mmap(machine, addr, map->start);
+
        return 0;
 }
 
index 7afeb80cc39eed61632940ea163165a6f7a11da7..d14464c42714b84d738e151eb9a71d4269cc37ab 100644 (file)
@@ -224,15 +224,15 @@ event_def: event_pmu |
           event_bpf_file
 
 event_pmu:
-PE_NAME opt_event_config
+PE_NAME '/' event_config '/'
 {
        struct list_head *list, *orig_terms, *terms;
 
-       if (parse_events_copy_term_list($2, &orig_terms))
+       if (parse_events_copy_term_list($3, &orig_terms))
                YYABORT;
 
        ALLOC_LIST(list);
-       if (parse_events_add_pmu(_parse_state, list, $1, $2, false)) {
+       if (parse_events_add_pmu(_parse_state, list, $1, $3, false)) {
                struct perf_pmu *pmu = NULL;
                int ok = 0;
                char *pattern;
@@ -262,7 +262,7 @@ PE_NAME opt_event_config
                if (!ok)
                        YYABORT;
        }
-       parse_events_terms__delete($2);
+       parse_events_terms__delete($3);
        parse_events_terms__delete(orig_terms);
        $$ = list;
 }
index 61a5e5027338159e6c4d7ec8472e0b732bc037f2..d2fb597c9a8c78d8e8fd8a9890e67f8b8f4432d7 100644 (file)
@@ -539,9 +539,10 @@ static bool pmu_is_uncore(const char *name)
 
 /*
  *  PMU CORE devices have different name other than cpu in sysfs on some
- *  platforms. looking for possible sysfs files to identify as core device.
+ *  platforms.
+ *  Looking for possible sysfs files to identify the arm core device.
  */
-static int is_pmu_core(const char *name)
+static int is_arm_pmu_core(const char *name)
 {
        struct stat st;
        char path[PATH_MAX];
@@ -550,12 +551,6 @@ static int is_pmu_core(const char *name)
        if (!sysfs)
                return 0;
 
-       /* Look for cpu sysfs (x86 and others) */
-       scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs);
-       if ((stat(path, &st) == 0) &&
-                       (strncmp(name, "cpu", strlen("cpu")) == 0))
-               return 1;
-
        /* Look for cpu sysfs (specific to arm) */
        scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus",
                                sysfs, name);
@@ -586,7 +581,7 @@ char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused)
  * cpuid string generated on this platform.
  * Otherwise return non-zero.
  */
-int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
+int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid)
 {
        regex_t re;
        regmatch_t pmatch[1];
@@ -668,6 +663,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
        struct pmu_events_map *map;
        struct pmu_event *pe;
        const char *name = pmu->name;
+       const char *pname;
 
        map = perf_pmu__find_map(pmu);
        if (!map)
@@ -686,11 +682,9 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu)
                        break;
                }
 
-               if (!is_pmu_core(name)) {
-                       /* check for uncore devices */
-                       if (pe->pmu == NULL)
-                               continue;
-                       if (strncmp(pe->pmu, name, strlen(pe->pmu)))
+               if (!is_arm_pmu_core(name)) {
+                       pname = pe->pmu ? pe->pmu : "cpu";
+                       if (strncmp(pname, name, strlen(pname)))
                                continue;
                }
 
index 826f38d5dd19f1a0455cdc1074bdd83b6dce02c5..261c81f086064e922da966f8a1497e1b724e2d85 100644 (file)
@@ -4,6 +4,7 @@
 all:
 
 TEST_PROGS := fw_run_tests.sh
+TEST_FILES := fw_fallback.sh fw_filesystem.sh fw_lib.sh
 
 include ../lib.mk
 
index 9ea31b57d71a60008430b56a1b1498ed0184ec86..962d7f4ac6276c598bedf42755e5f711a9c51925 100755 (executable)
@@ -154,11 +154,13 @@ test_finish()
        if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
                echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
        fi
-       if [ "$OLD_FWPATH" = "" ]; then
-               OLD_FWPATH=" "
-       fi
        if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
-               echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
+               if [ "$OLD_FWPATH" = "" ]; then
+                       # A zero-length write won't work; write a null byte
+                       printf '\000' >/sys/module/firmware_class/parameters/path
+               else
+                       echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
+               fi
        fi
        if [ -f $FW ]; then
                rm -f "$FW"
index 06d638e9dc62748bf33bfbf7dbcb37f9494fdc00..cffdd4eb0a57ccc76b6da44b6f557cec1798f72d 100755 (executable)
@@ -66,5 +66,5 @@ if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
        run_test_config_0003
 else
        echo "Running basic kernel configuration, working with your config"
-       run_test
+       run_tests
 fi
index 40370354d4c11e48f9404eccfbda1b5bf03cd682..c9c3281077bca413b9164547c9a3da9a2a061103 100644 (file)
@@ -100,12 +100,19 @@ asm (
        "       shl     $32, %r8\n"
        "       orq     $0x7f7f7f7f, %r8\n"
        "       movq    %r8, %r9\n"
-       "       movq    %r8, %r10\n"
-       "       movq    %r8, %r11\n"
-       "       movq    %r8, %r12\n"
-       "       movq    %r8, %r13\n"
-       "       movq    %r8, %r14\n"
-       "       movq    %r8, %r15\n"
+       "       incq    %r9\n"
+       "       movq    %r9, %r10\n"
+       "       incq    %r10\n"
+       "       movq    %r10, %r11\n"
+       "       incq    %r11\n"
+       "       movq    %r11, %r12\n"
+       "       incq    %r12\n"
+       "       movq    %r12, %r13\n"
+       "       incq    %r13\n"
+       "       movq    %r13, %r14\n"
+       "       incq    %r14\n"
+       "       movq    %r14, %r15\n"
+       "       incq    %r15\n"
        "       ret\n"
        "       .code32\n"
        "       .popsection\n"
@@ -128,12 +135,13 @@ int check_regs64(void)
        int err = 0;
        int num = 8;
        uint64_t *r64 = &regs64.r8;
+       uint64_t expected = 0x7f7f7f7f7f7f7f7fULL;
 
        if (!kernel_is_64bit)
                return 0;
 
        do {
-               if (*r64 == 0x7f7f7f7f7f7f7f7fULL)
+               if (*r64 == expected++)
                        continue; /* register did not change */
                if (syscall_addr != (long)&int80) {
                        /*
@@ -147,18 +155,17 @@ int check_regs64(void)
                                continue;
                        }
                } else {
-                       /* INT80 syscall entrypoint can be used by
+                       /*
+                        * INT80 syscall entrypoint can be used by
                         * 64-bit programs too, unlike SYSCALL/SYSENTER.
                         * Therefore it must preserve R12+
                         * (they are callee-saved registers in 64-bit C ABI).
                         *
-                        * This was probably historically not intended,
-                        * but R8..11 are clobbered (cleared to 0).
-                        * IOW: they are the only registers which aren't
-                        * preserved across INT80 syscall.
+                        * Starting in Linux 4.17 (and any kernel that
+                        * backports the change), R8..11 are preserved.
+                        * Historically (and probably unintentionally), they
+                        * were clobbered or zeroed.
                         */
-                       if (*r64 == 0 && num <= 11)
-                               continue;
                }
                printf("[FAIL]\tR%d has changed:%016llx\n", num, *r64);
                err++;
index dba629c5f8acd17eb7ef1743bf7fa0641094ed44..a4c1b76240df2d8a818fbef3ea73aac68f713fb2 100644 (file)
@@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
 static atomic64_t kvm_vmid_gen = ATOMIC64_INIT(1);
 static u32 kvm_next_vmid;
 static unsigned int kvm_vmid_bits __read_mostly;
-static DEFINE_SPINLOCK(kvm_vmid_lock);
+static DEFINE_RWLOCK(kvm_vmid_lock);
 
 static bool vgic_present;
 
@@ -473,11 +473,16 @@ static void update_vttbr(struct kvm *kvm)
 {
        phys_addr_t pgd_phys;
        u64 vmid;
+       bool new_gen;
 
-       if (!need_new_vmid_gen(kvm))
+       read_lock(&kvm_vmid_lock);
+       new_gen = need_new_vmid_gen(kvm);
+       read_unlock(&kvm_vmid_lock);
+
+       if (!new_gen)
                return;
 
-       spin_lock(&kvm_vmid_lock);
+       write_lock(&kvm_vmid_lock);
 
        /*
         * We need to re-check the vmid_gen here to ensure that if another vcpu
@@ -485,7 +490,7 @@ static void update_vttbr(struct kvm *kvm)
         * use the same vmid.
         */
        if (!need_new_vmid_gen(kvm)) {
-               spin_unlock(&kvm_vmid_lock);
+               write_unlock(&kvm_vmid_lock);
                return;
        }
 
@@ -519,7 +524,7 @@ static void update_vttbr(struct kvm *kvm)
        vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK(kvm_vmid_bits);
        kvm->arch.vttbr = kvm_phys_to_vttbr(pgd_phys) | vmid;
 
-       spin_unlock(&kvm_vmid_lock);
+       write_unlock(&kvm_vmid_lock);
 }
 
 static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
index 6919352cbf15e8d50b3742e32acfd152be4b18a8..c4762bef13c6d389ff0c1e4f656322d66bb167b0 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/preempt.h>
 #include <linux/kvm_host.h>
+#include <linux/uaccess.h>
 #include <linux/wait.h>
 
 #include <asm/cputype.h>
@@ -427,3 +428,62 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
        smccc_set_retval(vcpu, val, 0, 0, 0);
        return 1;
 }
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
+{
+       return 1;               /* PSCI version */
+}
+
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+       if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices))
+               return -EFAULT;
+
+       return 0;
+}
+
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+       if (reg->id == KVM_REG_ARM_PSCI_VERSION) {
+               void __user *uaddr = (void __user *)(long)reg->addr;
+               u64 val;
+
+               val = kvm_psci_version(vcpu, vcpu->kvm);
+               if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
+                       return -EFAULT;
+
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+       if (reg->id == KVM_REG_ARM_PSCI_VERSION) {
+               void __user *uaddr = (void __user *)(long)reg->addr;
+               bool wants_02;
+               u64 val;
+
+               if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
+                       return -EFAULT;
+
+               wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
+
+               switch (val) {
+               case KVM_ARM_PSCI_0_1:
+                       if (wants_02)
+                               return -EINVAL;
+                       vcpu->kvm->arch.psci_version = val;
+                       return 0;
+               case KVM_ARM_PSCI_0_2:
+               case KVM_ARM_PSCI_1_0:
+                       if (!wants_02)
+                               return -EINVAL;
+                       vcpu->kvm->arch.psci_version = val;
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
index e21e2f49b005256543fa912b8b33df8c134ff726..ffc587bf4742676d14930d21f07005275576a79e 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/irqchip/arm-gic.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
+#include <linux/nospec.h>
+
 #include <kvm/iodev.h>
 #include <kvm/arm_vgic.h>
 
@@ -324,6 +326,9 @@ static unsigned long vgic_mmio_read_apr(struct kvm_vcpu *vcpu,
 
                if (n > vgic_v3_max_apr_idx(vcpu))
                        return 0;
+
+               n = array_index_nospec(n, 4);
+
                /* GICv3 only uses ICH_AP1Rn for memory mapped (GICv2) guests */
                return vgicv3->vgic_ap1r[n];
        }
index e74baec7636130c6e379c93c7312a0be70f97a59..702936cbe173013086a2a60349ed34a041152877 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 #include <linux/list_sort.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
+#include <linux/nospec.h>
+
 #include <asm/kvm_hyp.h>
 
 #include "vgic.h"
@@ -101,12 +103,16 @@ struct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu,
                              u32 intid)
 {
        /* SGIs and PPIs */
-       if (intid <= VGIC_MAX_PRIVATE)
+       if (intid <= VGIC_MAX_PRIVATE) {
+               intid = array_index_nospec(intid, VGIC_MAX_PRIVATE);
                return &vcpu->arch.vgic_cpu.private_irqs[intid];
+       }
 
        /* SPIs */
-       if (intid <= VGIC_MAX_SPI)
+       if (intid <= VGIC_MAX_SPI) {
+               intid = array_index_nospec(intid, VGIC_MAX_SPI);
                return &kvm->arch.vgic.spis[intid - VGIC_NR_PRIVATE_IRQS];
+       }
 
        /* LPIs */
        if (intid >= VGIC_MIN_LPI)
@@ -594,6 +600,7 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
 
        list_for_each_entry_safe(irq, tmp, &vgic_cpu->ap_list_head, ap_list) {
                struct kvm_vcpu *target_vcpu, *vcpuA, *vcpuB;
+               bool target_vcpu_needs_kick = false;
 
                spin_lock(&irq->irq_lock);
 
@@ -664,11 +671,18 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu)
                        list_del(&irq->ap_list);
                        irq->vcpu = target_vcpu;
                        list_add_tail(&irq->ap_list, &new_cpu->ap_list_head);
+                       target_vcpu_needs_kick = true;
                }
 
                spin_unlock(&irq->irq_lock);
                spin_unlock(&vcpuB->arch.vgic_cpu.ap_list_lock);
                spin_unlock_irqrestore(&vcpuA->arch.vgic_cpu.ap_list_lock, flags);
+
+               if (target_vcpu_needs_kick) {
+                       kvm_make_request(KVM_REQ_IRQ_PENDING, target_vcpu);
+                       kvm_vcpu_kick(target_vcpu);
+               }
+
                goto retry;
        }