Merge branch 'linus' into sched/core, to pick up fixes
authorIngo Molnar <mingo@kernel.org>
Tue, 23 May 2017 07:50:35 +0000 (09:50 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 23 May 2017 07:50:35 +0000 (09:50 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
449 files changed:
Documentation/acpi/acpi-lid.txt
Documentation/admin-guide/pm/cpufreq.rst
Documentation/admin-guide/pm/index.rst
Documentation/admin-guide/pm/intel_pstate.rst [new file with mode: 0644]
Documentation/cpu-freq/intel-pstate.txt [deleted file]
Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt [deleted file]
Documentation/usb/typec.rst
Documentation/watchdog/watchdog-parameters.txt
MAINTAINERS
Makefile
arch/alpha/kernel/osf_sys.c
arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi
arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/imx53-qsrb.dts
arch/arm/boot/dts/imx6sx-sdb.dts
arch/arm/boot/dts/include/arm [deleted symlink]
arch/arm/boot/dts/include/arm64 [deleted symlink]
arch/arm/boot/dts/include/dt-bindings [deleted symlink]
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
arch/arm/boot/dts/mt7623.dtsi
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap4-panda-a4.dts
arch/arm/boot/dts/omap4-panda-es.dts
arch/arm/configs/gemini_defconfig [new file with mode: 0644]
arch/arm/include/asm/kvm_coproc.h
arch/arm/kvm/coproc.c
arch/arm/kvm/handle_exit.c
arch/arm/kvm/hyp/Makefile
arch/arm/kvm/hyp/switch.c
arch/arm/kvm/trace.h
arch/arm/mach-at91/pm.c
arch/arm/mach-bcm/bcm_kona_smc.c
arch/arm/mach-cns3xxx/core.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap-smp.c
arch/arm/mach-omap2/prm_common.c
arch/arm/mach-omap2/vc.c
arch/arm/mach-spear/time.c
arch/arm64/Kconfig.platforms
arch/arm64/boot/dts/include/arm [deleted symlink]
arch/arm64/boot/dts/include/arm64 [deleted symlink]
arch/arm64/boot/dts/include/dt-bindings [deleted symlink]
arch/arm64/boot/dts/marvell/armada-3720-db.dts
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/mediatek/mt8173-evb.dts
arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts
arch/arm64/configs/defconfig
arch/arm64/include/asm/atomic_ll_sc.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/kvm_host.h
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/perf_event.c
arch/arm64/kvm/hyp/Makefile
arch/arm64/net/bpf_jit_comp.c
arch/cris/boot/dts/include/dt-bindings [deleted symlink]
arch/metag/boot/dts/include/dt-bindings [deleted symlink]
arch/mips/boot/dts/include/dt-bindings [deleted symlink]
arch/powerpc/boot/dts/include/dt-bindings [deleted symlink]
arch/powerpc/include/asm/module.h
arch/powerpc/include/asm/page.h
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/process.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/Makefile
arch/powerpc/kvm/book3s_64_vio_hv.c
arch/powerpc/kvm/book3s_hv_builtin.c
arch/powerpc/kvm/book3s_pr_papr.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/dump_linuxpagetables.c
arch/s390/include/asm/debug.h
arch/s390/include/asm/dis.h
arch/s390/include/asm/kprobes.h
arch/s390/include/asm/sysinfo.h
arch/s390/kernel/debug.c
arch/s390/kernel/entry.S
arch/s390/kernel/ftrace.c
arch/s390/kernel/vmlinux.lds.S
arch/s390/lib/probes.c
arch/s390/lib/uaccess.c
arch/sparc/include/asm/hugetlb.h
arch/sparc/include/asm/pgtable_32.h
arch/sparc/include/asm/setup.h
arch/sparc/kernel/ftrace.c
arch/sparc/mm/init_32.c
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/uaccess.h
arch/x86/kernel/fpu/init.c
arch/x86/kvm/emulate.c
arch/x86/kvm/paging_tmpl.h
arch/x86/kvm/pmu_intel.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/mmu.c
arch/x86/xen/mmu_pv.c
crypto/skcipher.c
drivers/acpi/button.c
drivers/base/power/wakeup.c
drivers/block/drbd/drbd_req.c
drivers/block/xen-blkback/xenbus.c
drivers/char/lp.c
drivers/char/mem.c
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/Makefile
drivers/dax/super.c
drivers/edac/amd64_edac.c
drivers/firmware/efi/efi-pstore.c
drivers/firmware/google/vpd.c
drivers/firmware/ti_sci.c
drivers/gpu/drm/arm/hdlcd_crtc.c
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c
drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/render.c
drivers/gpu/drm/i915/gvt/sched_policy.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_dsi.c
drivers/gpu/drm/i915/intel_lpe_audio.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/ls_ucode_gr.c
drivers/gpu/host1x/Kconfig
drivers/hwmon/coretemp.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-xgene-slimpro.c
drivers/i2c/i2c-mux.c
drivers/i2c/muxes/i2c-mux-reg.c
drivers/iommu/dma-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/mtk_iommu_v1.c
drivers/irqchip/irq-mbigen.c
drivers/md/dm-bufio.c
drivers/md/dm-cache-background-tracker.c
drivers/md/dm-cache-policy-smq.c
drivers/md/dm-cache-target.c
drivers/md/dm-mpath.c
drivers/md/dm-rq.c
drivers/md/dm-thin-metadata.c
drivers/md/md.c
drivers/md/md.h
drivers/md/persistent-data/dm-space-map-disk.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid5-cache.c
drivers/md/raid5-log.h
drivers/md/raid5.c
drivers/memory/omap-gpmc.c
drivers/misc/Kconfig
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
drivers/net/ethernet/atheros/atlx/atl2.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h
drivers/net/ethernet/faraday/ftmac100.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/Kconfig
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
drivers/net/ethernet/mellanox/mlx5/core/ipoib.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_ctx.c
drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
drivers/net/ethernet/qualcomm/qca_spi.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/sfc/nic.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/sun/ldmvsw.c
drivers/net/ethernet/ti/netcp_core.c
drivers/net/ethernet/ti/netcp_ethss.c
drivers/net/irda/irda-usb.c
drivers/net/macvlan.c
drivers/net/phy/mdio-mux.c
drivers/net/phy/mdio_bus.c
drivers/net/usb/ch9200.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/smsc95xx.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vrf.c
drivers/net/xen-netfront.c
drivers/nvme/host/fc.c
drivers/nvme/host/pci.c
drivers/nvme/target/core.c
drivers/nvme/target/fc.c
drivers/nvme/target/fcloop.c
drivers/nvme/target/nvmet.h
drivers/nvme/target/rdma.c
drivers/of/fdt.c
drivers/of/of_reserved_mem.c
drivers/powercap/powercap_sys.c
drivers/rtc/rtc-cmos.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/qdio_debug.h
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_sys.c
drivers/s390/net/qeth_l2.h
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l2_sys.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/cxlflash/Kconfig
drivers/scsi/libfc/fc_fcp.c
drivers/scsi/lpfc/lpfc_crtn.h
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/pmcraid.c
drivers/scsi/qedf/qedf.h
drivers/scsi/qedf/qedf_els.c
drivers/scsi/qedf/qedf_main.c
drivers/scsi/scsi.c
drivers/scsi/scsi_lib.c
drivers/soc/bcm/brcmstb/common.c
drivers/soc/imx/Kconfig
drivers/soc/ti/knav_dma.c
drivers/staging/android/ion/devicetree.txt [deleted file]
drivers/staging/ccree/ssi_request_mgr.c
drivers/staging/fsl-dpaa2/Kconfig
drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
drivers/staging/rtl8192e/rtl819x_TSProc.c
drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c
drivers/staging/typec/fusb302/fusb302.c
drivers/staging/typec/pd.h
drivers/staging/typec/pd_vdo.h
drivers/staging/typec/tcpci.c
drivers/staging/typec/tcpm.c
drivers/staging/typec/tcpm.h
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
drivers/tee/Kconfig
drivers/uio/uio.c
drivers/usb/core/devio.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/of.c
drivers/usb/core/urb.c
drivers/usb/dwc3/dwc3-keystone.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/udc/dummy_hcd.c
drivers/usb/host/ehci-platform.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-plat.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/misc/chaoskey.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/sisusbvga/sisusb_con.c
drivers/usb/musb/musb_host.c
drivers/usb/musb/tusb6010_omap.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/io_ti.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/storage/ene_ub6250.c
drivers/usb/usbip/vhci_hcd.c
drivers/uwb/i1480/dfu/usb.c
drivers/watchdog/Kconfig
drivers/watchdog/bcm_kona_wdt.c
drivers/watchdog/cadence_wdt.c
drivers/watchdog/iTCO_wdt.c
drivers/watchdog/pcwd_usb.c
drivers/watchdog/sama5d4_wdt.c
drivers/watchdog/wdt_pci.c
drivers/watchdog/zx2967_wdt.c
fs/cifs/cifsacl.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/smb2pdu.c
fs/cifs/transport.c
fs/cifs/xattr.c
fs/ext2/inode.c
fs/ext4/inode.c
fs/fuse/inode.c
fs/xfs/xfs_iomap.c
include/kvm/arm_vgic.h
include/linux/bpf_verifier.h
include/linux/dax.h
include/linux/kprobes.h
include/linux/mlx5/fs.h
include/linux/netdevice.h
include/linux/netfilter/x_tables.h
include/linux/netfilter_bridge/ebtables.h
include/linux/nvme-fc-driver.h
include/linux/of_irq.h
include/linux/soc/renesas/rcar-rst.h
include/linux/usb/hcd.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_tables.h
include/net/x25.h
include/uapi/linux/bpf.h
include/uapi/linux/if_link.h
include/uapi/linux/usb/ch11.h
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/fork.c
kernel/irq/chip.c
kernel/kprobes.c
kernel/pid_namespace.c
kernel/power/snapshot.c
kernel/sched/cpufreq_schedutil.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_kprobe.c
net/9p/trans_xen.c
net/bridge/br_netlink.c
net/bridge/br_stp_if.c
net/bridge/br_stp_timer.c
net/bridge/netfilter/ebt_arpreply.c
net/bridge/netfilter/ebtables.c
net/core/dev.c
net/core/neighbour.c
net/core/rtnetlink.c
net/core/sock.c
net/dccp/ipv6.c
net/ipv4/arp.c
net/ipv4/fib_frontend.c
net/ipv4/fib_trie.c
net/ipv4/ipmr.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/udp.c
net/ipv4/udp_impl.h
net/ipv6/addrconf.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_output.c
net/ipv6/output_core.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipv6/udp_offload.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_nat_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_cthelper.c
net/netfilter/nft_bitwise.c
net/netfilter/nft_cmp.c
net/netfilter/nft_ct.c
net/netfilter/nft_immediate.c
net/netfilter/nft_range.c
net/netfilter/nft_set_hash.c
net/netfilter/x_tables.c
net/netfilter/xt_CT.c
net/openvswitch/conntrack.c
net/packet/af_packet.c
net/sched/cls_matchall.c
net/sched/sch_api.c
net/sctp/ipv6.c
net/smc/Kconfig
net/smc/smc_clc.c
net/smc/smc_core.c
net/smc/smc_core.h
net/smc/smc_ib.c
net/smc/smc_ib.h
net/tipc/socket.c
net/vmw_vsock/af_vsock.c
net/x25/af_x25.c
net/x25/sysctl_net_x25.c
samples/bpf/cookie_uid_helper_example.c
samples/bpf/offwaketime_user.c
samples/bpf/sampleip_user.c
samples/bpf/trace_event_user.c
samples/bpf/tracex2_user.c
samples/bpf/xdp1_user.c
samples/bpf/xdp_tx_iptunnel_user.c
scripts/Makefile.headersinst
scripts/Makefile.lib
scripts/dtc/checks.c
scripts/dtc/include-prefixes/arc [new symlink]
scripts/dtc/include-prefixes/arm [new symlink]
scripts/dtc/include-prefixes/arm64 [new symlink]
scripts/dtc/include-prefixes/c6x [new symlink]
scripts/dtc/include-prefixes/cris [new symlink]
scripts/dtc/include-prefixes/dt-bindings [new symlink]
scripts/dtc/include-prefixes/h8300 [new symlink]
scripts/dtc/include-prefixes/metag [new symlink]
scripts/dtc/include-prefixes/microblaze [new symlink]
scripts/dtc/include-prefixes/mips [new symlink]
scripts/dtc/include-prefixes/nios2 [new symlink]
scripts/dtc/include-prefixes/openrisc [new symlink]
scripts/dtc/include-prefixes/powerpc [new symlink]
scripts/dtc/include-prefixes/sh [new symlink]
scripts/dtc/include-prefixes/xtensa [new symlink]
sound/x86/intel_hdmi_audio.c
tools/build/feature/test-bpf.c
tools/include/uapi/linux/bpf.h
tools/lib/bpf/bpf.c
tools/lib/bpf/bpf.h
tools/power/acpi/.gitignore [new file with mode: 0644]
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/include/uapi/linux/types.h [new file with mode: 0644]
tools/testing/selftests/bpf/test_align.c [new file with mode: 0644]
tools/testing/selftests/bpf/test_pkt_access.c
tools/testing/selftests/ftrace/ftracetest
tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
tools/testing/selftests/ftrace/test.d/functions
tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
tools/testing/selftests/powerpc/tm/.gitignore
tools/testing/selftests/powerpc/tm/Makefile
tools/testing/selftests/powerpc/tm/tm-vmx-unavail.c [new file with mode: 0644]
virt/kvm/arm/hyp/vgic-v3-sr.c
virt/kvm/arm/mmu.c
virt/kvm/arm/vgic/vgic-init.c
virt/kvm/arm/vgic/vgic-mmio-v3.c
virt/kvm/arm/vgic/vgic-v2.c
virt/kvm/arm/vgic/vgic-v3.c

index 22cb3091f29776b2acfb0df339db150393a8ad83..effe7af3a5af95d25f86efadaa7dd2b127a0dea9 100644 (file)
@@ -59,20 +59,28 @@ button driver uses the following 3 modes in order not to trigger issues.
 If the userspace hasn't been prepared to ignore the unreliable "opened"
 events and the unreliable initial state notification, Linux users can use
 the following kernel parameters to handle the possible issues:
-A. button.lid_init_state=open:
+A. button.lid_init_state=method:
+   When this option is specified, the ACPI button driver reports the
+   initial lid state using the returning value of the _LID control method
+   and whether the "opened"/"closed" events are paired fully relies on the
+   firmware implementation.
+   This option can be used to fix some platforms where the returning value
+   of the _LID control method is reliable but the initial lid state
+   notification is missing.
+   This option is the default behavior during the period the userspace
+   isn't ready to handle the buggy AML tables.
+B. button.lid_init_state=open:
    When this option is specified, the ACPI button driver always reports the
    initial lid state as "opened" and whether the "opened"/"closed" events
    are paired fully relies on the firmware implementation.
    This may fix some platforms where the returning value of the _LID
    control method is not reliable and the initial lid state notification is
    missing.
-   This option is the default behavior during the period the userspace
-   isn't ready to handle the buggy AML tables.
 
 If the userspace has been prepared to ignore the unreliable "opened" events
 and the unreliable initial state notification, Linux users should always
 use the following kernel parameter:
-B. button.lid_init_state=ignore:
+C. button.lid_init_state=ignore:
    When this option is specified, the ACPI button driver never reports the
    initial lid state and there is a compensation mechanism implemented to
    ensure that the reliable "closed" notifications can always be delievered
index 289c80f7760ebb966b13d91b5627e61963e5b3aa..09aa2e9497875acec984dc68727e14139c5d23ad 100644 (file)
@@ -1,4 +1,5 @@
 .. |struct cpufreq_policy| replace:: :c:type:`struct cpufreq_policy <cpufreq_policy>`
+.. |intel_pstate| replace:: :doc:`intel_pstate <intel_pstate>`
 
 =======================
 CPU Performance Scaling
@@ -75,7 +76,7 @@ feedback registers, as that information is typically specific to the hardware
 interface it comes from and may not be easily represented in an abstract,
 platform-independent way.  For this reason, ``CPUFreq`` allows scaling drivers
 to bypass the governor layer and implement their own performance scaling
-algorithms.  That is done by the ``intel_pstate`` scaling driver.
+algorithms.  That is done by the |intel_pstate| scaling driver.
 
 
 ``CPUFreq`` Policy Objects
@@ -174,13 +175,13 @@ necessary to restart the scaling governor so that it can take the new online CPU
 into account.  That is achieved by invoking the governor's ``->stop`` and
 ``->start()`` callbacks, in this order, for the entire policy.
 
-As mentioned before, the ``intel_pstate`` scaling driver bypasses the scaling
+As mentioned before, the |intel_pstate| scaling driver bypasses the scaling
 governor layer of ``CPUFreq`` and provides its own P-state selection algorithms.
-Consequently, if ``intel_pstate`` is used, scaling governors are not attached to
+Consequently, if |intel_pstate| is used, scaling governors are not attached to
 new policy objects.  Instead, the driver's ``->setpolicy()`` callback is invoked
 to register per-CPU utilization update callbacks for each policy.  These
 callbacks are invoked by the CPU scheduler in the same way as for scaling
-governors, but in the ``intel_pstate`` case they both determine the P-state to
+governors, but in the |intel_pstate| case they both determine the P-state to
 use and change the hardware configuration accordingly in one go from scheduler
 context.
 
@@ -257,7 +258,7 @@ are the following:
 
 ``scaling_available_governors``
        List of ``CPUFreq`` scaling governors present in the kernel that can
-       be attached to this policy or (if the ``intel_pstate`` scaling driver is
+       be attached to this policy or (if the |intel_pstate| scaling driver is
        in use) list of scaling algorithms provided by the driver that can be
        applied to this policy.
 
@@ -274,7 +275,7 @@ are the following:
        the CPU is actually running at (due to hardware design and other
        limitations).
 
-       Some scaling drivers (e.g. ``intel_pstate``) attempt to provide
+       Some scaling drivers (e.g. |intel_pstate|) attempt to provide
        information more precisely reflecting the current CPU frequency through
        this attribute, but that still may not be the exact current CPU
        frequency as seen by the hardware at the moment.
@@ -284,13 +285,13 @@ are the following:
 
 ``scaling_governor``
        The scaling governor currently attached to this policy or (if the
-       ``intel_pstate`` scaling driver is in use) the scaling algorithm
+       |intel_pstate| scaling driver is in use) the scaling algorithm
        provided by the driver that is currently applied to this policy.
 
        This attribute is read-write and writing to it will cause a new scaling
        governor to be attached to this policy or a new scaling algorithm
        provided by the scaling driver to be applied to it (in the
-       ``intel_pstate`` case), as indicated by the string written to this
+       |intel_pstate| case), as indicated by the string written to this
        attribute (which must be one of the names listed by the
        ``scaling_available_governors`` attribute described above).
 
@@ -619,7 +620,7 @@ This file is located under :file:`/sys/devices/system/cpu/cpufreq/` and controls
 the "boost" setting for the whole system.  It is not present if the underlying
 scaling driver does not support the frequency boost mechanism (or supports it,
 but provides a driver-specific interface for controlling it, like
-``intel_pstate``).
+|intel_pstate|).
 
 If the value in this file is 1, the frequency boost mechanism is enabled.  This
 means that either the hardware can be put into states in which it is able to
index c80f087321fcb704e549254c70ccb927f9659b4c..7f148f76f432cbfc62ed663a6be7b9849b66b3c6 100644 (file)
@@ -6,6 +6,7 @@ Power Management
    :maxdepth: 2
 
    cpufreq
+   intel_pstate
 
 .. only::  subproject and html
 
diff --git a/Documentation/admin-guide/pm/intel_pstate.rst b/Documentation/admin-guide/pm/intel_pstate.rst
new file mode 100644 (file)
index 0000000..33d7039
--- /dev/null
@@ -0,0 +1,755 @@
+===============================================
+``intel_pstate`` CPU Performance Scaling Driver
+===============================================
+
+::
+
+ Copyright (c) 2017 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+
+General Information
+===================
+
+``intel_pstate`` is a part of the
+:doc:`CPU performance scaling subsystem <cpufreq>` in the Linux kernel
+(``CPUFreq``).  It is a scaling driver for the Sandy Bridge and later
+generations of Intel processors.  Note, however, that some of those processors
+may not be supported.  [To understand ``intel_pstate`` it is necessary to know
+how ``CPUFreq`` works in general, so this is the time to read :doc:`cpufreq` if
+you have not done that yet.]
+
+For the processors supported by ``intel_pstate``, the P-state concept is broader
+than just an operating frequency or an operating performance point (see the
+`LinuxCon Europe 2015 presentation by Kristen Accardi <LCEU2015_>`_ for more
+information about that).  For this reason, the representation of P-states used
+by ``intel_pstate`` internally follows the hardware specification (for details
+refer to `Intel® 64 and IA-32 Architectures Software Developer’s Manual
+Volume 3: System Programming Guide <SDM_>`_).  However, the ``CPUFreq`` core
+uses frequencies for identifying operating performance points of CPUs and
+frequencies are involved in the user space interface exposed by it, so
+``intel_pstate`` maps its internal representation of P-states to frequencies too
+(fortunately, that mapping is unambiguous).  At the same time, it would not be
+practical for ``intel_pstate`` to supply the ``CPUFreq`` core with a table of
+available frequencies due to the possible size of it, so the driver does not do
+that.  Some functionality of the core is limited by that.
+
+Since the hardware P-state selection interface used by ``intel_pstate`` is
+available at the logical CPU level, the driver always works with individual
+CPUs.  Consequently, if ``intel_pstate`` is in use, every ``CPUFreq`` policy
+object corresponds to one logical CPU and ``CPUFreq`` policies are effectively
+equivalent to CPUs.  In particular, this means that they become "inactive" every
+time the corresponding CPU is taken offline and need to be re-initialized when
+it goes back online.
+
+``intel_pstate`` is not modular, so it cannot be unloaded, which means that the
+only way to pass early-configuration-time parameters to it is via the kernel
+command line.  However, its configuration can be adjusted via ``sysfs`` to a
+great extent.  In some configurations it even is possible to unregister it via
+``sysfs`` which allows another ``CPUFreq`` scaling driver to be loaded and
+registered (see `below <status_attr_>`_).
+
+
+Operation Modes
+===============
+
+``intel_pstate`` can operate in three different modes: in the active mode with
+or without hardware-managed P-states support and in the passive mode.  Which of
+them will be in effect depends on what kernel command line options are used and
+on the capabilities of the processor.
+
+Active Mode
+-----------
+
+This is the default operation mode of ``intel_pstate``.  If it works in this
+mode, the ``scaling_driver`` policy attribute in ``sysfs`` for all ``CPUFreq``
+policies contains the string "intel_pstate".
+
+In this mode the driver bypasses the scaling governors layer of ``CPUFreq`` and
+provides its own scaling algorithms for P-state selection.  Those algorithms
+can be applied to ``CPUFreq`` policies in the same way as generic scaling
+governors (that is, through the ``scaling_governor`` policy attribute in
+``sysfs``).  [Note that different P-state selection algorithms may be chosen for
+different policies, but that is not recommended.]
+
+They are not generic scaling governors, but their names are the same as the
+names of some of those governors.  Moreover, confusingly enough, they generally
+do not work in the same way as the generic governors they share the names with.
+For example, the ``powersave`` P-state selection algorithm provided by
+``intel_pstate`` is not a counterpart of the generic ``powersave`` governor
+(roughly, it corresponds to the ``schedutil`` and ``ondemand`` governors).
+
+There are two P-state selection algorithms provided by ``intel_pstate`` in the
+active mode: ``powersave`` and ``performance``.  The way they both operate
+depends on whether or not the hardware-managed P-states (HWP) feature has been
+enabled in the processor and possibly on the processor model.
+
+Which of the P-state selection algorithms is used by default depends on the
+:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option.
+Namely, if that option is set, the ``performance`` algorithm will be used by
+default, and the other one will be used by default if it is not set.
+
+Active Mode With HWP
+~~~~~~~~~~~~~~~~~~~~
+
+If the processor supports the HWP feature, it will be enabled during the
+processor initialization and cannot be disabled after that.  It is possible
+to avoid enabling it by passing the ``intel_pstate=no_hwp`` argument to the
+kernel in the command line.
+
+If the HWP feature has been enabled, ``intel_pstate`` relies on the processor to
+select P-states by itself, but still it can give hints to the processor's
+internal P-state selection logic.  What those hints are depends on which P-state
+selection algorithm has been applied to the given policy (or to the CPU it
+corresponds to).
+
+Even though the P-state selection is carried out by the processor automatically,
+``intel_pstate`` registers utilization update callbacks with the CPU scheduler
+in this mode.  However, they are not used for running a P-state selection
+algorithm, but for periodic updates of the current CPU frequency information to
+be made available from the ``scaling_cur_freq`` policy attribute in ``sysfs``.
+
+HWP + ``performance``
+.....................
+
+In this configuration ``intel_pstate`` will write 0 to the processor's
+Energy-Performance Preference (EPP) knob (if supported) or its
+Energy-Performance Bias (EPB) knob (otherwise), which means that the processor's
+internal P-state selection logic is expected to focus entirely on performance.
+
+This will override the EPP/EPB setting coming from the ``sysfs`` interface
+(see `Energy vs Performance Hints`_ below).
+
+Also, in this configuration the range of P-states available to the processor's
+internal P-state selection logic is always restricted to the upper boundary
+(that is, the maximum P-state that the driver is allowed to use).
+
+HWP + ``powersave``
+...................
+
+In this configuration ``intel_pstate`` will set the processor's
+Energy-Performance Preference (EPP) knob (if supported) or its
+Energy-Performance Bias (EPB) knob (otherwise) to whatever value it was
+previously set to via ``sysfs`` (or whatever default value it was
+set to by the platform firmware).  This usually causes the processor's
+internal P-state selection logic to be less performance-focused.
+
+Active Mode Without HWP
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the default operation mode for processors that do not support the HWP
+feature.  It also is used by default with the ``intel_pstate=no_hwp`` argument
+in the kernel command line.  However, in this mode ``intel_pstate`` may refuse
+to work with the given processor if it does not recognize it.  [Note that
+``intel_pstate`` will never refuse to work with any processor with the HWP
+feature enabled.]
+
+In this mode ``intel_pstate`` registers utilization update callbacks with the
+CPU scheduler in order to run a P-state selection algorithm, either
+``powersave`` or ``performance``, depending on the ``scaling_cur_freq`` policy
+setting in ``sysfs``.  The current CPU frequency information to be made
+available from the ``scaling_cur_freq`` policy attribute in ``sysfs`` is
+periodically updated by those utilization update callbacks too.
+
+``performance``
+...............
+
+Without HWP, this P-state selection algorithm is always the same regardless of
+the processor model and platform configuration.
+
+It selects the maximum P-state it is allowed to use, subject to limits set via
+``sysfs``, every time the P-state selection computations are carried out by the
+driver's utilization update callback for the given CPU (that does not happen
+more often than every 10 ms), but the hardware configuration will not be changed
+if the new P-state is the same as the current one.
+
+This is the default P-state selection algorithm if the
+:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option
+is set.
+
+``powersave``
+.............
+
+Without HWP, this P-state selection algorithm generally depends on the
+processor model and/or the system profile setting in the ACPI tables and there
+are two variants of it.
+
+One of them is used with processors from the Atom line and (regardless of the
+processor model) on platforms with the system profile in the ACPI tables set to
+"mobile" (laptops mostly), "tablet", "appliance PC", "desktop", or
+"workstation".  It is also used with processors supporting the HWP feature if
+that feature has not been enabled (that is, with the ``intel_pstate=no_hwp``
+argument in the kernel command line).  It is similar to the algorithm
+implemented by the generic ``schedutil`` scaling governor except that the
+utilization metric used by it is based on numbers coming from feedback
+registers of the CPU.  It generally selects P-states proportional to the
+current CPU utilization, so it is referred to as the "proportional" algorithm.
+
+The second variant of the ``powersave`` P-state selection algorithm, used in all
+of the other cases (generally, on processors from the Core line, so it is
+referred to as the "Core" algorithm), is based on the values read from the APERF
+and MPERF feedback registers and the previously requested target P-state.
+It does not really take CPU utilization into account explicitly, but as a rule
+it causes the CPU P-state to ramp up very quickly in response to increased
+utilization which is generally desirable in server environments.
+
+Regardless of the variant, this algorithm is run by the driver's utilization
+update callback for the given CPU when it is invoked by the CPU scheduler, but
+not more often than every 10 ms (that can be tweaked via ``debugfs`` in `this
+particular case <Tuning Interface in debugfs_>`_).  Like in the ``performance``
+case, the hardware configuration is not touched if the new P-state turns out to
+be the same as the current one.
+
+This is the default P-state selection algorithm if the
+:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option
+is not set.
+
+Passive Mode
+------------
+
+This mode is used if the ``intel_pstate=passive`` argument is passed to the
+kernel in the command line (it implies the ``intel_pstate=no_hwp`` setting too).
+Like in the active mode without HWP support, in this mode ``intel_pstate`` may
+refuse to work with the given processor if it does not recognize it.
+
+If the driver works in this mode, the ``scaling_driver`` policy attribute in
+``sysfs`` for all ``CPUFreq`` policies contains the string "intel_cpufreq".
+Then, the driver behaves like a regular ``CPUFreq`` scaling driver.  That is,
+it is invoked by generic scaling governors when necessary to talk to the
+hardware in order to change the P-state of a CPU (in particular, the
+``schedutil`` governor can invoke it directly from scheduler context).
+
+While in this mode, ``intel_pstate`` can be used with all of the (generic)
+scaling governors listed by the ``scaling_available_governors`` policy attribute
+in ``sysfs`` (and the P-state selection algorithms described above are not
+used).  Then, it is responsible for the configuration of policy objects
+corresponding to CPUs and provides the ``CPUFreq`` core (and the scaling
+governors attached to the policy objects) with accurate information on the
+maximum and minimum operating frequencies supported by the hardware (including
+the so-called "turbo" frequency ranges).  In other words, in the passive mode
+the entire range of available P-states is exposed by ``intel_pstate`` to the
+``CPUFreq`` core.  However, in this mode the driver does not register
+utilization update callbacks with the CPU scheduler and the ``scaling_cur_freq``
+information comes from the ``CPUFreq`` core (and is the last frequency selected
+by the current scaling governor for the given policy).
+
+
+.. _turbo:
+
+Turbo P-states Support
+======================
+
+In the majority of cases, the entire range of P-states available to
+``intel_pstate`` can be divided into two sub-ranges that correspond to
+different types of processor behavior, above and below a boundary that
+will be referred to as the "turbo threshold" in what follows.
+
+The P-states above the turbo threshold are referred to as "turbo P-states" and
+the whole sub-range of P-states they belong to is referred to as the "turbo
+range".  These names are related to the Turbo Boost technology allowing a
+multicore processor to opportunistically increase the P-state of one or more
+cores if there is enough power to do that and if that is not going to cause the
+thermal envelope of the processor package to be exceeded.
+
+Specifically, if software sets the P-state of a CPU core within the turbo range
+(that is, above the turbo threshold), the processor is permitted to take over
+performance scaling control for that core and put it into turbo P-states of its
+choice going forward.  However, that permission is interpreted differently by
+different processor generations.  Namely, the Sandy Bridge generation of
+processors will never use any P-states above the last one set by software for
+the given core, even if it is within the turbo range, whereas all of the later
+processor generations will take it as a license to use any P-states from the
+turbo range, even above the one set by software.  In other words, on those
+processors setting any P-state from the turbo range will enable the processor
+to put the given core into all turbo P-states up to and including the maximum
+supported one as it sees fit.
+
+One important property of turbo P-states is that they are not sustainable.  More
+precisely, there is no guarantee that any CPUs will be able to stay in any of
+those states indefinitely, because the power distribution within the processor
+package may change over time  or the thermal envelope it was designed for might
+be exceeded if a turbo P-state was used for too long.
+
+In turn, the P-states below the turbo threshold generally are sustainable.  In
+fact, if one of them is set by software, the processor is not expected to change
+it to a lower one unless in a thermal stress or a power limit violation
+situation (a higher P-state may still be used if it is set for another CPU in
+the same package at the same time, for example).
+
+Some processors allow multiple cores to be in turbo P-states at the same time,
+but the maximum P-state that can be set for them generally depends on the number
+of cores running concurrently.  The maximum turbo P-state that can be set for 3
+cores at the same time usually is lower than the analogous maximum P-state for
+2 cores, which in turn usually is lower than the maximum turbo P-state that can
+be set for 1 core.  The one-core maximum turbo P-state is thus the maximum
+supported one overall.
+
+The maximum supported turbo P-state, the turbo threshold (the maximum supported
+non-turbo P-state) and the minimum supported P-state are specific to the
+processor model and can be determined by reading the processor's model-specific
+registers (MSRs).  Moreover, some processors support the Configurable TDP
+(Thermal Design Power) feature and, when that feature is enabled, the turbo
+threshold effectively becomes a configurable value that can be set by the
+platform firmware.
+
+Unlike ``_PSS`` objects in the ACPI tables, ``intel_pstate`` always exposes
+the entire range of available P-states, including the whole turbo range, to the
+``CPUFreq`` core and (in the passive mode) to generic scaling governors.  This
+generally causes turbo P-states to be set more often when ``intel_pstate`` is
+used relative to ACPI-based CPU performance scaling (see `below <acpi-cpufreq_>`_
+for more information).
+
+Moreover, since ``intel_pstate`` always knows what the real turbo threshold is
+(even if the Configurable TDP feature is enabled in the processor), its
+``no_turbo`` attribute in ``sysfs`` (described `below <no_turbo_attr_>`_) should
+work as expected in all cases (that is, if set to disable turbo P-states, it
+always should prevent ``intel_pstate`` from using them).
+
+
+Processor Support
+=================
+
+To handle a given processor ``intel_pstate`` requires a number of different
+pieces of information on it to be known, including:
+
+ * The minimum supported P-state.
+
+ * The maximum supported `non-turbo P-state <turbo_>`_.
+
+ * Whether or not turbo P-states are supported at all.
+
+ * The maximum supported `one-core turbo P-state <turbo_>`_ (if turbo P-states
+   are supported).
+
+ * The scaling formula to translate the driver's internal representation
+   of P-states into frequencies and the other way around.
+
+Generally, ways to obtain that information are specific to the processor model
+or family.  Although it often is possible to obtain all of it from the processor
+itself (using model-specific registers), there are cases in which hardware
+manuals need to be consulted to get to it too.
+
+For this reason, there is a list of supported processors in ``intel_pstate`` and
+the driver initialization will fail if the detected processor is not in that
+list, unless it supports the `HWP feature <Active Mode_>`_.  [The interface to
+obtain all of the information listed above is the same for all of the processors
+supporting the HWP feature, which is why they all are supported by
+``intel_pstate``.]
+
+
+User Space Interface in ``sysfs``
+=================================
+
+Global Attributes
+-----------------
+
+``intel_pstate`` exposes several global attributes (files) in ``sysfs`` to
+control its functionality at the system level.  They are located in the
+``/sys/devices/system/cpu/cpufreq/intel_pstate/`` directory and affect all
+CPUs.
+
+Some of them are not present if the ``intel_pstate=per_cpu_perf_limits``
+argument is passed to the kernel in the command line.
+
+``max_perf_pct``
+       Maximum P-state the driver is allowed to set in percent of the
+       maximum supported performance level (the highest supported `turbo
+       P-state <turbo_>`_).
+
+       This attribute will not be exposed if the
+       ``intel_pstate=per_cpu_perf_limits`` argument is present in the kernel
+       command line.
+
+``min_perf_pct``
+       Minimum P-state the driver is allowed to set in percent of the
+       maximum supported performance level (the highest supported `turbo
+       P-state <turbo_>`_).
+
+       This attribute will not be exposed if the
+       ``intel_pstate=per_cpu_perf_limits`` argument is present in the kernel
+       command line.
+
+``num_pstates``
+       Number of P-states supported by the processor (between 0 and 255
+       inclusive) including both turbo and non-turbo P-states (see
+       `Turbo P-states Support`_).
+
+       The value of this attribute is not affected by the ``no_turbo``
+       setting described `below <no_turbo_attr_>`_.
+
+       This attribute is read-only.
+
+``turbo_pct``
+       Ratio of the `turbo range <turbo_>`_ size to the size of the entire
+       range of supported P-states, in percent.
+
+       This attribute is read-only.
+
+.. _no_turbo_attr:
+
+``no_turbo``
+       If set (equal to 1), the driver is not allowed to set any turbo P-states
+       (see `Turbo P-states Support`_).  If unset (equalt to 0, which is the
+       default), turbo P-states can be set by the driver.
+       [Note that ``intel_pstate`` does not support the general ``boost``
+       attribute (supported by some other scaling drivers) which is replaced
+       by this one.]
+
+       This attrubute does not affect the maximum supported frequency value
+       supplied to the ``CPUFreq`` core and exposed via the policy interface,
+       but it affects the maximum possible value of per-policy P-state limits
+       (see `Interpretation of Policy Attributes`_ below for details).
+
+.. _status_attr:
+
+``status``
+       Operation mode of the driver: "active", "passive" or "off".
+
+       "active"
+               The driver is functional and in the `active mode
+               <Active Mode_>`_.
+
+       "passive"
+               The driver is functional and in the `passive mode
+               <Passive Mode_>`_.
+
+       "off"
+               The driver is not functional (it is not registered as a scaling
+               driver with the ``CPUFreq`` core).
+
+       This attribute can be written to in order to change the driver's
+       operation mode or to unregister it.  The string written to it must be
+       one of the possible values of it and, if successful, the write will
+       cause the driver to switch over to the operation mode represented by
+       that string - or to be unregistered in the "off" case.  [Actually,
+       switching over from the active mode to the passive mode or the other
+       way around causes the driver to be unregistered and registered again
+       with a different set of callbacks, so all of its settings (the global
+       as well as the per-policy ones) are then reset to their default
+       values, possibly depending on the target operation mode.]
+
+       That only is supported in some configurations, though (for example, if
+       the `HWP feature is enabled in the processor <Active Mode With HWP_>`_,
+       the operation mode of the driver cannot be changed), and if it is not
+       supported in the current configuration, writes to this attribute with
+       fail with an appropriate error.
+
+Interpretation of Policy Attributes
+-----------------------------------
+
+The interpretation of some ``CPUFreq`` policy attributes described in
+:doc:`cpufreq` is special with ``intel_pstate`` as the current scaling driver
+and it generally depends on the driver's `operation mode <Operation Modes_>`_.
+
+First of all, the values of the ``cpuinfo_max_freq``, ``cpuinfo_min_freq`` and
+``scaling_cur_freq`` attributes are produced by applying a processor-specific
+multiplier to the internal P-state representation used by ``intel_pstate``.
+Also, the values of the ``scaling_max_freq`` and ``scaling_min_freq``
+attributes are capped by the frequency corresponding to the maximum P-state that
+the driver is allowed to set.
+
+If the ``no_turbo`` `global attribute <no_turbo_attr_>`_ is set, the driver is
+not allowed to use turbo P-states, so the maximum value of ``scaling_max_freq``
+and ``scaling_min_freq`` is limited to the maximum non-turbo P-state frequency.
+Accordingly, setting ``no_turbo`` causes ``scaling_max_freq`` and
+``scaling_min_freq`` to go down to that value if they were above it before.
+However, the old values of ``scaling_max_freq`` and ``scaling_min_freq`` will be
+restored after unsetting ``no_turbo``, unless these attributes have been written
+to after ``no_turbo`` was set.
+
+If ``no_turbo`` is not set, the maximum possible value of ``scaling_max_freq``
+and ``scaling_min_freq`` corresponds to the maximum supported turbo P-state,
+which also is the value of ``cpuinfo_max_freq`` in either case.
+
+Next, the following policy attributes have special meaning if
+``intel_pstate`` works in the `active mode <Active Mode_>`_:
+
+``scaling_available_governors``
+       List of P-state selection algorithms provided by ``intel_pstate``.
+
+``scaling_governor``
+       P-state selection algorithm provided by ``intel_pstate`` currently in
+       use with the given policy.
+
+``scaling_cur_freq``
+       Frequency of the average P-state of the CPU represented by the given
+       policy for the time interval between the last two invocations of the
+       driver's utilization update callback by the CPU scheduler for that CPU.
+
+The meaning of these attributes in the `passive mode <Passive Mode_>`_ is the
+same as for other scaling drivers.
+
+Additionally, the value of the ``scaling_driver`` attribute for ``intel_pstate``
+depends on the operation mode of the driver.  Namely, it is either
+"intel_pstate" (in the `active mode <Active Mode_>`_) or "intel_cpufreq" (in the
+`passive mode <Passive Mode_>`_).
+
+Coordination of P-State Limits
+------------------------------
+
+``intel_pstate`` allows P-state limits to be set in two ways: with the help of
+the ``max_perf_pct`` and ``min_perf_pct`` `global attributes
+<Global Attributes_>`_ or via the ``scaling_max_freq`` and ``scaling_min_freq``
+``CPUFreq`` policy attributes.  The coordination between those limits is based
+on the following rules, regardless of the current operation mode of the driver:
+
+ 1. All CPUs are affected by the global limits (that is, none of them can be
+    requested to run faster than the global maximum and none of them can be
+    requested to run slower than the global minimum).
+
+ 2. Each individual CPU is affected by its own per-policy limits (that is, it
+    cannot be requested to run faster than its own per-policy maximum and it
+    cannot be requested to run slower than its own per-policy minimum).
+
+ 3. The global and per-policy limits can be set independently.
+
+If the `HWP feature is enabled in the processor <Active Mode With HWP_>`_, the
+resulting effective values are written into its registers whenever the limits
+change in order to request its internal P-state selection logic to always set
+P-states within these limits.  Otherwise, the limits are taken into account by
+scaling governors (in the `passive mode <Passive Mode_>`_) and by the driver
+every time before setting a new P-state for a CPU.
+
+Additionally, if the ``intel_pstate=per_cpu_perf_limits`` command line argument
+is passed to the kernel, ``max_perf_pct`` and ``min_perf_pct`` are not exposed
+at all and the only way to set the limits is by using the policy attributes.
+
+
+Energy vs Performance Hints
+---------------------------
+
+If ``intel_pstate`` works in the `active mode with the HWP feature enabled
+<Active Mode With HWP_>`_ in the processor, additional attributes are present
+in every ``CPUFreq`` policy directory in ``sysfs``.  They are intended to allow
+user space to help ``intel_pstate`` to adjust the processor's internal P-state
+selection logic by focusing it on performance or on energy-efficiency, or
+somewhere between the two extremes:
+
+``energy_performance_preference``
+       Current value of the energy vs performance hint for the given policy
+       (or the CPU represented by it).
+
+       The hint can be changed by writing to this attribute.
+
+``energy_performance_available_preferences``
+       List of strings that can be written to the
+       ``energy_performance_preference`` attribute.
+
+       They represent different energy vs performance hints and should be
+       self-explanatory, except that ``default`` represents whatever hint
+       value was set by the platform firmware.
+
+Strings written to the ``energy_performance_preference`` attribute are
+internally translated to integer values written to the processor's
+Energy-Performance Preference (EPP) knob (if supported) or its
+Energy-Performance Bias (EPB) knob.
+
+[Note that tasks may by migrated from one CPU to another by the scheduler's
+load-balancing algorithm and if different energy vs performance hints are
+set for those CPUs, that may lead to undesirable outcomes.  To avoid such
+issues it is better to set the same energy vs performance hint for all CPUs
+or to pin every task potentially sensitive to them to a specific CPU.]
+
+.. _acpi-cpufreq:
+
+``intel_pstate`` vs ``acpi-cpufreq``
+====================================
+
+On the majority of systems supported by ``intel_pstate``, the ACPI tables
+provided by the platform firmware contain ``_PSS`` objects returning information
+that can be used for CPU performance scaling (refer to the `ACPI specification`_
+for details on the ``_PSS`` objects and the format of the information returned
+by them).
+
+The information returned by the ACPI ``_PSS`` objects is used by the
+``acpi-cpufreq`` scaling driver.  On systems supported by ``intel_pstate``
+the ``acpi-cpufreq`` driver uses the same hardware CPU performance scaling
+interface, but the set of P-states it can use is limited by the ``_PSS``
+output.
+
+On those systems each ``_PSS`` object returns a list of P-states supported by
+the corresponding CPU which basically is a subset of the P-states range that can
+be used by ``intel_pstate`` on the same system, with one exception: the whole
+`turbo range <turbo_>`_ is represented by one item in it (the topmost one).  By
+convention, the frequency returned by ``_PSS`` for that item is greater by 1 MHz
+than the frequency of the highest non-turbo P-state listed by it, but the
+corresponding P-state representation (following the hardware specification)
+returned for it matches the maximum supported turbo P-state (or is the
+special value 255 meaning essentially "go as high as you can get").
+
+The list of P-states returned by ``_PSS`` is reflected by the table of
+available frequencies supplied by ``acpi-cpufreq`` to the ``CPUFreq`` core and
+scaling governors and the minimum and maximum supported frequencies reported by
+it come from that list as well.  In particular, given the special representation
+of the turbo range described above, this means that the maximum supported
+frequency reported by ``acpi-cpufreq`` is higher by 1 MHz than the frequency
+of the highest supported non-turbo P-state listed by ``_PSS`` which, of course,
+affects decisions made by the scaling governors, except for ``powersave`` and
+``performance``.
+
+For example, if a given governor attempts to select a frequency proportional to
+estimated CPU load and maps the load of 100% to the maximum supported frequency
+(possibly multiplied by a constant), then it will tend to choose P-states below
+the turbo threshold if ``acpi-cpufreq`` is used as the scaling driver, because
+in that case the turbo range corresponds to a small fraction of the frequency
+band it can use (1 MHz vs 1 GHz or more).  In consequence, it will only go to
+the turbo range for the highest loads and the other loads above 50% that might
+benefit from running at turbo frequencies will be given non-turbo P-states
+instead.
+
+One more issue related to that may appear on systems supporting the
+`Configurable TDP feature <turbo_>`_ allowing the platform firmware to set the
+turbo threshold.  Namely, if that is not coordinated with the lists of P-states
+returned by ``_PSS`` properly, there may be more than one item corresponding to
+a turbo P-state in those lists and there may be a problem with avoiding the
+turbo range (if desirable or necessary).  Usually, to avoid using turbo
+P-states overall, ``acpi-cpufreq`` simply avoids using the topmost state listed
+by ``_PSS``, but that is not sufficient when there are other turbo P-states in
+the list returned by it.
+
+Apart from the above, ``acpi-cpufreq`` works like ``intel_pstate`` in the
+`passive mode <Passive Mode_>`_, except that the number of P-states it can set
+is limited to the ones listed by the ACPI ``_PSS`` objects.
+
+
+Kernel Command Line Options for ``intel_pstate``
+================================================
+
+Several kernel command line options can be used to pass early-configuration-time
+parameters to ``intel_pstate`` in order to enforce specific behavior of it.  All
+of them have to be prepended with the ``intel_pstate=`` prefix.
+
+``disable``
+       Do not register ``intel_pstate`` as the scaling driver even if the
+       processor is supported by it.
+
+``passive``
+       Register ``intel_pstate`` in the `passive mode <Passive Mode_>`_ to
+       start with.
+
+       This option implies the ``no_hwp`` one described below.
+
+``force``
+       Register ``intel_pstate`` as the scaling driver instead of
+       ``acpi-cpufreq`` even if the latter is preferred on the given system.
+
+       This may prevent some platform features (such as thermal controls and
+       power capping) that rely on the availability of ACPI P-states
+       information from functioning as expected, so it should be used with
+       caution.
+
+       This option does not work with processors that are not supported by
+       ``intel_pstate`` and on platforms where the ``pcc-cpufreq`` scaling
+       driver is used instead of ``acpi-cpufreq``.
+
+``no_hwp``
+       Do not enable the `hardware-managed P-states (HWP) feature
+       <Active Mode With HWP_>`_ even if it is supported by the processor.
+
+``hwp_only``
+       Register ``intel_pstate`` as the scaling driver only if the
+       `hardware-managed P-states (HWP) feature <Active Mode With HWP_>`_ is
+       supported by the processor.
+
+``support_acpi_ppc``
+       Take ACPI ``_PPC`` performance limits into account.
+
+       If the preferred power management profile in the FADT (Fixed ACPI
+       Description Table) is set to "Enterprise Server" or "Performance
+       Server", the ACPI ``_PPC`` limits are taken into account by default
+       and this option has no effect.
+
+``per_cpu_perf_limits``
+       Use per-logical-CPU P-State limits (see `Coordination of P-state
+       Limits`_ for details).
+
+
+Diagnostics and Tuning
+======================
+
+Trace Events
+------------
+
+There are two static trace events that can be used for ``intel_pstate``
+diagnostics.  One of them is the ``cpu_frequency`` trace event generally used
+by ``CPUFreq``, and the other one is the ``pstate_sample`` trace event specific
+to ``intel_pstate``.  Both of them are triggered by ``intel_pstate`` only if
+it works in the `active mode <Active Mode_>`_.
+
+The following sequence of shell commands can be used to enable them and see
+their output (if the kernel is generally configured to support event tracing)::
+
+ # cd /sys/kernel/debug/tracing/
+ # echo 1 > events/power/pstate_sample/enable
+ # echo 1 > events/power/cpu_frequency/enable
+ # cat trace
+ gnome-terminal--4510  [001] ..s.  1177.680733: pstate_sample: core_busy=107 scaled=94 from=26 to=26 mperf=1143818 aperf=1230607 tsc=29838618 freq=2474476
+ cat-5235  [002] ..s.  1177.681723: cpu_frequency: state=2900000 cpu_id=2
+
+If ``intel_pstate`` works in the `passive mode <Passive Mode_>`_, the
+``cpu_frequency`` trace event will be triggered either by the ``schedutil``
+scaling governor (for the policies it is attached to), or by the ``CPUFreq``
+core (for the policies with other scaling governors).
+
+``ftrace``
+----------
+
+The ``ftrace`` interface can be used for low-level diagnostics of
+``intel_pstate``.  For example, to check how often the function to set a
+P-state is called, the ``ftrace`` filter can be set to to
+:c:func:`intel_pstate_set_pstate`::
+
+ # cd /sys/kernel/debug/tracing/
+ # cat available_filter_functions | grep -i pstate
+ intel_pstate_set_pstate
+ intel_pstate_cpu_init
+ ...
+ # echo intel_pstate_set_pstate > set_ftrace_filter
+ # echo function > current_tracer
+ # cat trace | head -15
+ # tracer: function
+ #
+ # entries-in-buffer/entries-written: 80/80   #P:4
+ #
+ #                              _-----=> irqs-off
+ #                             / _----=> need-resched
+ #                            | / _---=> hardirq/softirq
+ #                            || / _--=> preempt-depth
+ #                            ||| /     delay
+ #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
+ #              | |       |   ||||       |         |
+             Xorg-3129  [000] ..s.  2537.644844: intel_pstate_set_pstate <-intel_pstate_timer_func
+  gnome-terminal--4510  [002] ..s.  2537.649844: intel_pstate_set_pstate <-intel_pstate_timer_func
+      gnome-shell-3409  [001] ..s.  2537.650850: intel_pstate_set_pstate <-intel_pstate_timer_func
+           <idle>-0     [000] ..s.  2537.654843: intel_pstate_set_pstate <-intel_pstate_timer_func
+
+Tuning Interface in ``debugfs``
+-------------------------------
+
+The ``powersave`` algorithm provided by ``intel_pstate`` for `the Core line of
+processors in the active mode <powersave_>`_ is based on a `PID controller`_
+whose parameters were chosen to address a number of different use cases at the
+same time.  However, it still is possible to fine-tune it to a specific workload
+and the ``debugfs`` interface under ``/sys/kernel/debug/pstate_snb/`` is
+provided for this purpose.  [Note that the ``pstate_snb`` directory will be
+present only if the specific P-state selection algorithm matching the interface
+in it actually is in use.]
+
+The following files present in that directory can be used to modify the PID
+controller parameters at run time:
+
+| ``deadband``
+| ``d_gain_pct``
+| ``i_gain_pct``
+| ``p_gain_pct``
+| ``sample_rate_ms``
+| ``setpoint``
+
+Note, however, that achieving desirable results this way generally requires
+expert-level understanding of the power vs performance tradeoff, so extra care
+is recommended when attempting to do that.
+
+
+.. _LCEU2015: http://events.linuxfoundation.org/sites/events/files/slides/LinuxConEurope_2015.pdf
+.. _SDM: http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-system-programming-manual-325384.html
+.. _ACPI specification: http://www.uefi.org/sites/default/files/resources/ACPI_6_1.pdf
+.. _PID controller: https://en.wikipedia.org/wiki/PID_controller
diff --git a/Documentation/cpu-freq/intel-pstate.txt b/Documentation/cpu-freq/intel-pstate.txt
deleted file mode 100644 (file)
index 3fdcdfd..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-Intel P-State driver
---------------------
-
-This driver provides an interface to control the P-State selection for the
-SandyBridge+ Intel processors.
-
-The following document explains P-States:
-http://events.linuxfoundation.org/sites/events/files/slides/LinuxConEurope_2015.pdf
-As stated in the document, P-State doesn’t exactly mean a frequency. However, for
-the sake of the relationship with cpufreq, P-State and frequency are used
-interchangeably.
-
-Understanding the cpufreq core governors and policies are important before
-discussing more details about the Intel P-State driver. Based on what callbacks
-a cpufreq driver provides to the cpufreq core, it can support two types of
-drivers:
-- with target_index() callback: In this mode, the drivers using cpufreq core
-simply provide the minimum and maximum frequency limits and an additional
-interface target_index() to set the current frequency. The cpufreq subsystem
-has a number of scaling governors ("performance", "powersave", "ondemand",
-etc.). Depending on which governor is in use, cpufreq core will call for
-transitions to a specific frequency using target_index() callback.
-- setpolicy() callback: In this mode, drivers do not provide target_index()
-callback, so cpufreq core can't request a transition to a specific frequency.
-The driver provides minimum and maximum frequency limits and callbacks to set a
-policy. The policy in cpufreq sysfs is referred to as the "scaling governor".
-The cpufreq core can request the driver to operate in any of the two policies:
-"performance" and "powersave". The driver decides which frequency to use based
-on the above policy selection considering minimum and maximum frequency limits.
-
-The Intel P-State driver falls under the latter category, which implements the
-setpolicy() callback. This driver decides what P-State to use based on the
-requested policy from the cpufreq core. If the processor is capable of
-selecting its next P-State internally, then the driver will offload this
-responsibility to the processor (aka HWP: Hardware P-States). If not, the
-driver implements algorithms to select the next P-State.
-
-Since these policies are implemented in the driver, they are not same as the
-cpufreq scaling governors implementation, even if they have the same name in
-the cpufreq sysfs (scaling_governors). For example the "performance" policy is
-similar to cpufreq’s "performance" governor, but "powersave" is completely
-different than the cpufreq "powersave" governor. The strategy here is similar
-to cpufreq "ondemand", where the requested P-State is related to the system load.
-
-Sysfs Interface
-
-In addition to the frequency-controlling interfaces provided by the cpufreq
-core, the driver provides its own sysfs files to control the P-State selection.
-These files have been added to /sys/devices/system/cpu/intel_pstate/.
-Any changes made to these files are applicable to all CPUs (even in a
-multi-package system, Refer to later section on placing "Per-CPU limits").
-
-      max_perf_pct: Limits the maximum P-State that will be requested by
-      the driver. It states it as a percentage of the available performance. The
-      available (P-State) performance may be reduced by the no_turbo
-      setting described below.
-
-      min_perf_pct: Limits the minimum P-State that will be requested by
-      the driver. It states it as a percentage of the max (non-turbo)
-      performance level.
-
-      no_turbo: Limits the driver to selecting P-State below the turbo
-      frequency range.
-
-      turbo_pct: Displays the percentage of the total performance that
-      is supported by hardware that is in the turbo range. This number
-      is independent of whether turbo has been disabled or not.
-
-      num_pstates: Displays the number of P-States that are supported
-      by hardware. This number is independent of whether turbo has
-      been disabled or not.
-
-For example, if a system has these parameters:
-       Max 1 core turbo ratio: 0x21 (Max 1 core ratio is the maximum P-State)
-       Max non turbo ratio: 0x17
-       Minimum ratio : 0x08 (Here the ratio is called max efficiency ratio)
-
-Sysfs will show :
-       max_perf_pct:100, which corresponds to 1 core ratio
-       min_perf_pct:24, max_efficiency_ratio / max 1 Core ratio
-       no_turbo:0, turbo is not disabled
-       num_pstates:26 = (max 1 Core ratio - Max Efficiency Ratio + 1)
-       turbo_pct:39 = (max 1 core ratio - max non turbo ratio) / num_pstates
-
-Refer to "Intel® 64 and IA-32 Architectures Software Developer’s Manual
-Volume 3: System Programming Guide" to understand ratios.
-
-There is one more sysfs attribute in /sys/devices/system/cpu/intel_pstate/
-that can be used for controlling the operation mode of the driver:
-
-      status: Three settings are possible:
-      "off"     - The driver is not in use at this time.
-      "active"  - The driver works as a P-state governor (default).
-      "passive" - The driver works as a regular cpufreq one and collaborates
-                  with the generic cpufreq governors (it sets P-states as
-                  requested by those governors).
-      The current setting is returned by reads from this attribute.  Writing one
-      of the above strings to it changes the operation mode as indicated by that
-      string, if possible.  If HW-managed P-states (HWP) are enabled, it is not
-      possible to change the driver's operation mode and attempts to write to
-      this attribute will fail.
-
-cpufreq sysfs for Intel P-State
-
-Since this driver registers with cpufreq, cpufreq sysfs is also presented.
-There are some important differences, which need to be considered.
-
-scaling_cur_freq: This displays the real frequency which was used during
-the last sample period instead of what is requested. Some other cpufreq driver,
-like acpi-cpufreq, displays what is requested (Some changes are on the
-way to fix this for acpi-cpufreq driver). The same is true for frequencies
-displayed at /proc/cpuinfo.
-
-scaling_governor: This displays current active policy. Since each CPU has a
-cpufreq sysfs, it is possible to set a scaling governor to each CPU. But this
-is not possible with Intel P-States, as there is one common policy for all
-CPUs. Here, the last requested policy will be applicable to all CPUs. It is
-suggested that one use the cpupower utility to change policy to all CPUs at the
-same time.
-
-scaling_setspeed: This attribute can never be used with Intel P-State.
-
-scaling_max_freq/scaling_min_freq: This interface can be used similarly to
-the max_perf_pct/min_perf_pct of Intel P-State sysfs. However since frequencies
-are converted to nearest possible P-State, this is prone to rounding errors.
-This method is not preferred to limit performance.
-
-affected_cpus: Not used
-related_cpus: Not used
-
-For contemporary Intel processors, the frequency is controlled by the
-processor itself and the P-State exposed to software is related to
-performance levels.  The idea that frequency can be set to a single
-frequency is fictional for Intel Core processors. Even if the scaling
-driver selects a single P-State, the actual frequency the processor
-will run at is selected by the processor itself.
-
-Per-CPU limits
-
-The kernel command line option "intel_pstate=per_cpu_perf_limits" forces
-the intel_pstate driver to use per-CPU performance limits.  When it is set,
-the sysfs control interface described above is subject to limitations.
-- The following controls are not available for both read and write
-       /sys/devices/system/cpu/intel_pstate/max_perf_pct
-       /sys/devices/system/cpu/intel_pstate/min_perf_pct
-- The following controls can be used to set performance limits, as far as the
-architecture of the processor permits:
-       /sys/devices/system/cpu/cpu*/cpufreq/scaling_max_freq
-       /sys/devices/system/cpu/cpu*/cpufreq/scaling_min_freq
-       /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
-- User can still observe turbo percent and number of P-States from
-       /sys/devices/system/cpu/intel_pstate/turbo_pct
-       /sys/devices/system/cpu/intel_pstate/num_pstates
-- User can read write system wide turbo status
-       /sys/devices/system/cpu/no_turbo
-
-Support of energy performance hints
-It is possible to provide hints to the HWP algorithms in the processor
-to be more performance centric to more energy centric. When the driver
-is using HWP, two additional cpufreq sysfs attributes are presented for
-each logical CPU.
-These attributes are:
-       - energy_performance_available_preferences
-       - energy_performance_preference
-
-To get list of supported hints:
-$ cat energy_performance_available_preferences
-    default performance balance_performance balance_power power
-
-The current preference can be read or changed via cpufreq sysfs
-attribute "energy_performance_preference". Reading from this attribute
-will display current effective setting. User can write any of the valid
-preference string to this attribute. User can always restore to power-on
-default by writing "default".
-
-Since threads can migrate to different CPUs, this is possible that the
-new CPU may have different energy performance preference than the previous
-one. To avoid such issues, either threads can be pinned to specific CPUs
-or set the same energy performance preference value to all CPUs.
-
-Tuning Intel P-State driver
-
-When the performance can be tuned using PID (Proportional Integral
-Derivative) controller, debugfs files are provided for adjusting performance.
-They are presented under:
-/sys/kernel/debug/pstate_snb/
-
-The PID tunable parameters are:
-      deadband
-      d_gain_pct
-      i_gain_pct
-      p_gain_pct
-      sample_rate_ms
-      setpoint
-
-To adjust these parameters, some understanding of driver implementation is
-necessary. There are some tweeks described here, but be very careful. Adjusting
-them requires expert level understanding of power and performance relationship.
-These limits are only useful when the "powersave" policy is active.
-
--To make the system more responsive to load changes, sample_rate_ms can
-be adjusted  (current default is 10ms).
--To make the system use higher performance, even if the load is lower, setpoint
-can be adjusted to a lower number. This will also lead to faster ramp up time
-to reach the maximum P-State.
-If there are no derivative and integral coefficients, The next P-State will be
-equal to:
-       current P-State - ((setpoint - current cpu load) * p_gain_pct)
-
-For example, if the current PID parameters are (Which are defaults for the core
-processors like SandyBridge):
-      deadband = 0
-      d_gain_pct = 0
-      i_gain_pct = 0
-      p_gain_pct = 20
-      sample_rate_ms = 10
-      setpoint = 97
-
-If the current P-State = 0x08 and current load = 100, this will result in the
-next P-State = 0x08 - ((97 - 100) * 0.2) = 8.6 (rounded to 9). Here the P-State
-goes up by only 1. If during next sample interval the current load doesn't
-change and still 100, then P-State goes up by one again. This process will
-continue as long as the load is more than the setpoint until the maximum P-State
-is reached.
-
-For the same load at setpoint = 60, this will result in the next P-State
-= 0x08 - ((60 - 100) * 0.2) = 16
-So by changing the setpoint from 97 to 60, there is an increase of the
-next P-State from 9 to 16. So this will make processor execute at higher
-P-State for the same CPU load. If the load continues to be more than the
-setpoint during next sample intervals, then P-State will go up again till the
-maximum P-State is reached. But the ramp up time to reach the maximum P-State
-will be much faster when the setpoint is 60 compared to 97.
-
-Debugging Intel P-State driver
-
-Event tracing
-To debug P-State transition, the Linux event tracing interface can be used.
-There are two specific events, which can be enabled (Provided the kernel
-configs related to event tracing are enabled).
-
-# cd /sys/kernel/debug/tracing/
-# echo 1 > events/power/pstate_sample/enable
-# echo 1 > events/power/cpu_frequency/enable
-# cat trace
-gnome-terminal--4510  [001] ..s.  1177.680733: pstate_sample: core_busy=107
-       scaled=94 from=26 to=26 mperf=1143818 aperf=1230607 tsc=29838618
-               freq=2474476
-cat-5235  [002] ..s.  1177.681723: cpu_frequency: state=2900000 cpu_id=2
-
-
-Using ftrace
-
-If function level tracing is required, the Linux ftrace interface can be used.
-For example if we want to check how often a function to set a P-State is
-called, we can set ftrace filter to intel_pstate_set_pstate.
-
-# cd /sys/kernel/debug/tracing/
-# cat available_filter_functions | grep -i pstate
-intel_pstate_set_pstate
-intel_pstate_cpu_init
-...
-
-# echo intel_pstate_set_pstate > set_ftrace_filter
-# echo function > current_tracer
-# cat trace | head -15
-# tracer: function
-#
-# entries-in-buffer/entries-written: 80/80   #P:4
-#
-#                              _-----=> irqs-off
-#                             / _----=> need-resched
-#                            | / _---=> hardirq/softirq
-#                            || / _--=> preempt-depth
-#                            ||| /     delay
-#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
-#              | |       |   ||||       |         |
-            Xorg-3129  [000] ..s.  2537.644844: intel_pstate_set_pstate <-intel_pstate_timer_func
- gnome-terminal--4510  [002] ..s.  2537.649844: intel_pstate_set_pstate <-intel_pstate_timer_func
-     gnome-shell-3409  [001] ..s.  2537.650850: intel_pstate_set_pstate <-intel_pstate_timer_func
-          <idle>-0     [000] ..s.  2537.654843: intel_pstate_set_pstate <-intel_pstate_timer_func
diff --git a/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt b/Documentation/devicetree/bindings/staging/ion/hi6220-ion.txt
deleted file mode 100644 (file)
index c59e27c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Hi6220 SoC ION
-===================================================================
-Required properties:
-- compatible : "hisilicon,hi6220-ion"
-- list of the ION heaps
-       - heap name : maybe heap_sys_user@0
-       - heap id   : id should be unique in the system.
-       - heap base : base ddr address of the heap,0 means that
-       it is dynamic.
-       - heap size : memory size and 0 means it is dynamic.
-       - heap type : the heap type of the heap, please also
-       see the define in ion.h(drivers/staging/android/uapi/ion.h)
--------------------------------------------------------------------
-Example:
-       hi6220-ion {
-               compatible = "hisilicon,hi6220-ion";
-               heap_sys_user@0 {
-                       heap-name = "sys_user";
-                       heap-id   = <0x0>;
-                       heap-base = <0x0>;
-                       heap-size = <0x0>;
-                       heap-type = "ion_system";
-               };
-               heap_sys_contig@0 {
-                       heap-name = "sys_contig";
-                       heap-id   = <0x1>;
-                       heap-base = <0x0>;
-                       heap-size = <0x0>;
-                       heap-type = "ion_system_contig";
-               };
-       };
index b67a46779de9fb7ee2d2c515718de3dab4914b37..8a7249f2ff04ca8c24e5ae9174fb1ba2a93d0461 100644 (file)
@@ -114,8 +114,7 @@ the details during registration. The class offers the following API for
 registering/unregistering cables and their plugs:
 
 .. kernel-doc:: drivers/usb/typec/typec.c
-   :functions: typec_register_cable typec_unregister_cable typec_register_plug
-   typec_unregister_plug
+   :functions: typec_register_cable typec_unregister_cable typec_register_plug typec_unregister_plug
 
 The class will provide a handle to struct typec_cable and struct typec_plug if
 the registration is successful, or NULL if it isn't.
@@ -137,8 +136,7 @@ during connection of a partner or cable, the port driver must use the following
 APIs to report it to the class:
 
 .. kernel-doc:: drivers/usb/typec/typec.c
-   :functions: typec_set_data_role typec_set_pwr_role typec_set_vconn_role
-   typec_set_pwr_opmode
+   :functions: typec_set_data_role typec_set_pwr_role typec_set_vconn_role typec_set_pwr_opmode
 
 Alternate Modes
 ~~~~~~~~~~~~~~~
index 4f7d86dd0a5d88802d85bb68ccf1f93715003a42..914518aeb972872e0fcd3057022d59070c9db282 100644 (file)
@@ -117,7 +117,7 @@ nowayout: Watchdog cannot be stopped once started
 -------------------------------------------------
 iTCO_wdt:
 heartbeat: Watchdog heartbeat in seconds.
-       (2<heartbeat<39 (TCO v1) or 613 (TCO v2), default=30)
+       (5<=heartbeat<=74 (TCO v1) or 1226 (TCO v2), default=30)
 nowayout: Watchdog cannot be stopped once started
        (default=kernel config parameter)
 -------------------------------------------------
index f7d568b8f133d9919e3823c102d7ac78f89c894a..9e984645c4b08b9e20ebc839704a5d25b0c32032 100644 (file)
@@ -846,7 +846,6 @@ M:  Laura Abbott <labbott@redhat.com>
 M:     Sumit Semwal <sumit.semwal@linaro.org>
 L:     devel@driverdev.osuosl.org
 S:     Supported
-F:     Documentation/devicetree/bindings/staging/ion/
 F:     drivers/staging/android/ion
 F:     drivers/staging/android/uapi/ion.h
 F:     drivers/staging/android/uapi/ion_test.h
@@ -3116,6 +3115,14 @@ F:       drivers/net/ieee802154/cc2520.c
 F:     include/linux/spi/cc2520.h
 F:     Documentation/devicetree/bindings/net/ieee802154/cc2520.txt
 
+CCREE ARM TRUSTZONE CRYPTOCELL 700 REE DRIVER
+M:     Gilad Ben-Yossef <gilad@benyossef.com>
+L:     linux-crypto@vger.kernel.org
+L:     driverdev-devel@linuxdriverproject.org
+S:     Supported
+F:     drivers/staging/ccree/
+W:     https://developer.arm.com/products/system-ip/trustzone-cryptocell/cryptocell-700-family
+
 CEC FRAMEWORK
 M:     Hans Verkuil <hans.verkuil@cisco.com>
 L:     linux-media@vger.kernel.org
@@ -5695,7 +5702,7 @@ M:        Alex Elder <elder@kernel.org>
 M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 S:     Maintained
 F:     drivers/staging/greybus/
-L:     greybus-dev@lists.linaro.org
+L:     greybus-dev@lists.linaro.org (moderated for non-subscribers)
 
 GREYBUS AUDIO PROTOCOLS DRIVERS
 M:     Vaibhav Agarwal <vaibhav.sr@gmail.com>
@@ -9553,10 +9560,6 @@ F:       drivers/net/wireless/intersil/orinoco/
 
 OSD LIBRARY and FILESYSTEM
 M:     Boaz Harrosh <ooo@electrozaur.com>
-M:     Benny Halevy <bhalevy@primarydata.com>
-L:     osd-dev@open-osd.org
-W:     http://open-osd.org
-T:     git git://git.open-osd.org/open-osd.git
 S:     Maintained
 F:     drivers/scsi/osd/
 F:     include/scsi/osd_*
index b400c0604facc79e86731a37e77c6620c61aa358..63e10bd4f14ac25297b3841eec5b2be6ee03035b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 12
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
@@ -1172,7 +1172,7 @@ headers_check_all: headers_install_all
 PHONY += headers_check
 headers_check: headers_install
        $(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
-       $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/ $(hdr-dst) HDRCHECK=1
+       $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi $(hdr-dst) HDRCHECK=1
 
 # ---------------------------------------------------------------------------
 # Kernel selftest
index 9ec56dc973749555019f5f0087727cc1bb97881a..ce93124a850be26520524579d30188e1ba5fcee6 100644 (file)
@@ -1201,8 +1201,10 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
        if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
                return -EFAULT;
 
-       err = 0;
-       err |= put_user(status, ustatus);
+       err = put_user(status, ustatus);
+       if (ret < 0)
+               return err ? err : ret;
+
        err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
        err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
        err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
index 12c981e5113489ea785d8f4d8b0a5b9f99d61beb..9a0599f711ff3382a7b908bb72e9f0392db5e1bf 100644 (file)
@@ -1,6 +1,6 @@
 / {
        aliases {
-               ethernet = &ethernet;
+               ethernet0 = &ethernet;
        };
 };
 
index 3f0a56ebcf1f64692cbdd311752ce8d1fd36a5f1..dc7ae776db5fc0ca54e91ef6369fbaee71162d22 100644 (file)
@@ -1,6 +1,6 @@
 / {
        aliases {
-               ethernet = &ethernet;
+               ethernet0 = &ethernet;
        };
 };
 
index 35cea3fcaf5c479e68e50e5d8e6606cb9735abba..561f27d8d92224fe8f4f8c3224a5441f2d41175a 100644 (file)
                                brcm,pins = <0 1>;
                                brcm,function = <BCM2835_FSEL_ALT0>;
                        };
-                       i2c0_gpio32: i2c0_gpio32 {
-                               brcm,pins = <32 34>;
+                       i2c0_gpio28: i2c0_gpio28 {
+                               brcm,pins = <28 29>;
                                brcm,function = <BCM2835_FSEL_ALT0>;
                        };
                        i2c0_gpio44: i2c0_gpio44 {
                        /* Separate from the uart0_gpio14 group
                         * because it conflicts with spi1_gpio16, and
                         * people often run uart0 on the two pins
-                        * without flow contrl.
+                        * without flow control.
                         */
                        uart0_ctsrts_gpio16: uart0_ctsrts_gpio16 {
                                brcm,pins = <16 17>;
                                brcm,function = <BCM2835_FSEL_ALT3>;
                        };
-                       uart0_gpio30: uart0_gpio30 {
+                       uart0_ctsrts_gpio30: uart0_ctsrts_gpio30 {
                                brcm,pins = <30 31>;
                                brcm,function = <BCM2835_FSEL_ALT3>;
                        };
-                       uart0_ctsrts_gpio32: uart0_ctsrts_gpio32 {
+                       uart0_gpio32: uart0_gpio32 {
                                brcm,pins = <32 33>;
                                brcm,function = <BCM2835_FSEL_ALT3>;
                        };
+                       uart0_gpio36: uart0_gpio36 {
+                               brcm,pins = <36 37>;
+                               brcm,function = <BCM2835_FSEL_ALT2>;
+                       };
+                       uart0_ctsrts_gpio38: uart0_ctsrts_gpio38 {
+                               brcm,pins = <38 39>;
+                               brcm,function = <BCM2835_FSEL_ALT2>;
+                       };
 
                        uart1_gpio14: uart1_gpio14 {
                                brcm,pins = <14 15>;
                                brcm,pins = <30 31>;
                                brcm,function = <BCM2835_FSEL_ALT5>;
                        };
-                       uart1_gpio36: uart1_gpio36 {
-                               brcm,pins = <36 37 38 39>;
-                               brcm,function = <BCM2835_FSEL_ALT2>;
-                       };
                        uart1_gpio40: uart1_gpio40 {
                                brcm,pins = <40 41>;
                                brcm,function = <BCM2835_FSEL_ALT5>;
index 4bc4b575c99bd43da80115cf4d8ee74845f3cc22..31a9e061ddd0d0f76b115890aab09dbd2ae340d9 100644 (file)
        tps659038: tps659038@58 {
                compatible = "ti,tps659038";
                reg = <0x58>;
+               ti,palmas-override-powerhold;
+               ti,system-power-controller;
 
                tps659038_pmic {
                        compatible = "ti,tps659038-pmic";
index 57892f264ceaee19ac08e4650a01ccd3f1c9866f..e7144662af45cc98974e648f2b6e2226e214df29 100644 (file)
        coefficients = <0 2000>;
 };
 
+&cpu_crit {
+       temperature = <120000>; /* milli Celsius */
+};
+
 /include/ "dra7xx-clocks.dtsi"
index de221583237276a5b4cd57c7de724c8cbbf9ec57..4e103a905dc9c9adb112caba85f2b7cff8f8ef1d 100644 (file)
@@ -23,7 +23,7 @@
        imx53-qsrb {
                pinctrl_pmic: pmicgrp {
                        fsl,pins = <
-                               MX53_PAD_CSI0_DAT5__GPIO5_23    0x1e4 /* IRQ */
+                               MX53_PAD_CSI0_DAT5__GPIO5_23    0x1c4 /* IRQ */
                        >;
                };
        };
index 5bb8fd57e7f5a83f6cbae6c2292f33c92446c4f7..d71da30c9cff2347900f9e68715b18d65597d47a 100644 (file)
        model = "Freescale i.MX6 SoloX SDB RevB Board";
 };
 
-&cpu0 {
-       operating-points = <
-               /* kHz    uV */
-               996000  1250000
-               792000  1175000
-               396000  1175000
-               198000  1175000
-               >;
-       fsl,soc-operating-points = <
-               /* ARM kHz      SOC uV */
-               996000  1250000
-               792000  1175000
-               396000  1175000
-               198000  1175000
-       >;
-};
-
 &i2c1 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/include/arm b/arch/arm/boot/dts/include/arm
deleted file mode 120000 (symlink)
index a96aa0e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-..
\ No newline at end of file
diff --git a/arch/arm/boot/dts/include/arm64 b/arch/arm/boot/dts/include/arm64
deleted file mode 120000 (symlink)
index 074a835..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../arm64/boot/dts
\ No newline at end of file
diff --git a/arch/arm/boot/dts/include/dt-bindings b/arch/arm/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
index 08cce17a25a01f460fd199f5f380bb3c907e20ed..43e9364083de84383a34815c04a6bd1021b3baa0 100644 (file)
                        OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0)   /* cam_xclka.cam_xclka */
                        OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0)   /* cam_pclk.cam_pclk */
 
-                       OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0)   /* cam_d0.cam_d0 */
-                       OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0)   /* cam_d1.cam_d1 */
-                       OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0)   /* cam_d2.cam_d2 */
+                       OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0)   /* cam_d0.cam_d0 */
+                       OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0)   /* cam_d1.cam_d1 */
+                       OMAP3_CORE1_IOPAD(0x211a, PIN_INPUT | MUX_MODE0)   /* cam_d2.cam_d2 */
                        OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0)   /* cam_d3.cam_d3 */
                        OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0)   /* cam_d4.cam_d4 */
                        OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0)   /* cam_d5.cam_d5 */
index 402579ab70d2b94a21f58fd8bea2eeb1885a9072..3a9e9b6aea6892784a3379fd39fb562c0869a0ba 100644 (file)
@@ -72,6 +72,8 @@
                             <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
                             <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
                             <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               clock-frequency = <13000000>;
+               arm,cpu-registers-not-fw-configured;
        };
 
        watchdog: watchdog@10007000 {
index b3a8b1f24499afe232d752ba16e15e45e4280d5b..9ec737069369672f6b52b26df840636cce768761 100644 (file)
@@ -55,7 +55,8 @@
                simple-audio-card,bitclock-master = <&telephony_link_master>;
                simple-audio-card,frame-master = <&telephony_link_master>;
                simple-audio-card,format = "i2s";
-
+               simple-audio-card,bitclock-inversion;
+               simple-audio-card,frame-inversion;
                simple-audio-card,cpu {
                        sound-dai = <&mcbsp4>;
                };
index 78d3631777629b8422deac792a6d2e6f1c655e7c..f1a6476af3716489007c12141d06f208ec2ebc94 100644 (file)
@@ -13,7 +13,7 @@
 /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
 &dss_hdmi_pins {
        pinctrl-single,pins = <
-               OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+               OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0)               /* hdmi_cec.hdmi_cec */
                OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)               /* hdmi_scl.hdmi_scl */
                OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)               /* hdmi_sda.hdmi_sda */
                >;
index 119f8e657edc9bae37089588968b660c9c3749da..940fe4f7c5f6e148a1e22e7b2daaadc91c627c10 100644 (file)
@@ -34,7 +34,7 @@
 /* PandaboardES has external pullups on SCL & SDA */
 &dss_hdmi_pins {
        pinctrl-single,pins = <
-               OMAP4_IOPAD(0x09a, PIN_INPUT_PULLUP | MUX_MODE0)        /* hdmi_cec.hdmi_cec */
+               OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0)               /* hdmi_cec.hdmi_cec */
                OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0)               /* hdmi_scl.hdmi_scl */
                OMAP4_IOPAD(0x09e, PIN_INPUT | MUX_MODE0)               /* hdmi_sda.hdmi_sda */
                >;
diff --git a/arch/arm/configs/gemini_defconfig b/arch/arm/configs/gemini_defconfig
new file mode 100644 (file)
index 0000000..d2d75fa
--- /dev/null
@@ -0,0 +1,68 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_USER_NS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_MULTI_V4=y
+# CONFIG_ARCH_MULTI_V7 is not set
+CONFIG_ARCH_GEMINI=y
+CONFIG_PCI=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="console=ttyS0,115200n8"
+CONFIG_KEXEC=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+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_WATCHDOG=y
+CONFIG_GEMINI_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_FOTG210_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GEMINI=y
+CONFIG_DMADEVICES=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ROMFS_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
index 4917c2f7e45955919509727640b9e54edd940b01..e74ab0fbab79091105dd1e5026c1e3e1e1347ead 100644 (file)
@@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table);
 int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
index 2c14b69511e981816861e16b31ed18dce0f2360f..6d1d2e26dfe5d8cd83e1a89a106f8028eed65c8e 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/vfp.h>
 #include "../vfp/vfpinstr.h"
 
+#define CREATE_TRACE_POINTS
 #include "trace.h"
 #include "coproc.h"
 
@@ -111,12 +112,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
        return 1;
 }
 
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-       kvm_inject_undefined(vcpu);
-       return 1;
-}
-
 static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
 {
        /*
@@ -284,7 +279,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
  * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
  * all PM registers, which doesn't crash the guest kernel at least.
  */
-static bool pm_fake(struct kvm_vcpu *vcpu,
+static bool trap_raz_wi(struct kvm_vcpu *vcpu,
                    const struct coproc_params *p,
                    const struct coproc_reg *r)
 {
@@ -294,19 +289,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
                return read_zero(vcpu, p);
 }
 
-#define access_pmcr pm_fake
-#define access_pmcntenset pm_fake
-#define access_pmcntenclr pm_fake
-#define access_pmovsr pm_fake
-#define access_pmselr pm_fake
-#define access_pmceid0 pm_fake
-#define access_pmceid1 pm_fake
-#define access_pmccntr pm_fake
-#define access_pmxevtyper pm_fake
-#define access_pmxevcntr pm_fake
-#define access_pmuserenr pm_fake
-#define access_pmintenset pm_fake
-#define access_pmintenclr pm_fake
+#define access_pmcr trap_raz_wi
+#define access_pmcntenset trap_raz_wi
+#define access_pmcntenclr trap_raz_wi
+#define access_pmovsr trap_raz_wi
+#define access_pmselr trap_raz_wi
+#define access_pmceid0 trap_raz_wi
+#define access_pmceid1 trap_raz_wi
+#define access_pmccntr trap_raz_wi
+#define access_pmxevtyper trap_raz_wi
+#define access_pmxevcntr trap_raz_wi
+#define access_pmuserenr trap_raz_wi
+#define access_pmintenset trap_raz_wi
+#define access_pmintenclr trap_raz_wi
 
 /* Architected CP15 registers.
  * CRn denotes the primary register number, but is copied to the CRm in the
@@ -532,12 +527,7 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
        return 1;
 }
 
-/**
- * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static struct coproc_params decode_64bit_hsr(struct kvm_vcpu *vcpu)
 {
        struct coproc_params params;
 
@@ -551,9 +541,38 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
        params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
        params.CRm = 0;
 
+       return params;
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+       struct coproc_params params = decode_64bit_hsr(vcpu);
+
        return emulate_cp15(vcpu, &params);
 }
 
+/**
+ * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+       struct coproc_params params = decode_64bit_hsr(vcpu);
+
+       /* raz_wi cp14 */
+       trap_raz_wi(vcpu, &params, NULL);
+
+       /* handled */
+       kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+       return 1;
+}
+
 static void reset_coproc_regs(struct kvm_vcpu *vcpu,
                              const struct coproc_reg *table, size_t num)
 {
@@ -564,12 +583,7 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
                        table[i].reset(vcpu, &table[i]);
 }
 
-/**
- * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu)
 {
        struct coproc_params params;
 
@@ -583,9 +597,37 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
        params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
        params.Rt2 = 0;
 
+       return params;
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+       struct coproc_params params = decode_32bit_hsr(vcpu);
        return emulate_cp15(vcpu, &params);
 }
 
+/**
+ * kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+       struct coproc_params params = decode_32bit_hsr(vcpu);
+
+       /* raz_wi cp14 */
+       trap_raz_wi(vcpu, &params, NULL);
+
+       /* handled */
+       kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+       return 1;
+}
+
 /******************************************************************************
  * Userspace API
  *****************************************************************************/
index 5fd7968cdae9efb4f68968eca13afebffb8c0be4..f86a9aaef462c6d861a80ae60bb26492ddb28d66 100644 (file)
@@ -95,9 +95,9 @@ static exit_handle_fn arm_exit_handlers[] = {
        [HSR_EC_WFI]            = kvm_handle_wfx,
        [HSR_EC_CP15_32]        = kvm_handle_cp15_32,
        [HSR_EC_CP15_64]        = kvm_handle_cp15_64,
-       [HSR_EC_CP14_MR]        = kvm_handle_cp14_access,
+       [HSR_EC_CP14_MR]        = kvm_handle_cp14_32,
        [HSR_EC_CP14_LS]        = kvm_handle_cp14_load_store,
-       [HSR_EC_CP14_64]        = kvm_handle_cp14_access,
+       [HSR_EC_CP14_64]        = kvm_handle_cp14_64,
        [HSR_EC_CP_0_13]        = kvm_handle_cp_0_13_access,
        [HSR_EC_CP10_ID]        = kvm_handle_cp10_id,
        [HSR_EC_HVC]            = handle_hvc,
index 3023bb530edf160ddbbe974e820227950a06ac31..8679405b0b2bb1e7a23232554bf26f71d7ae75ac 100644 (file)
@@ -2,6 +2,8 @@
 # Makefile for Kernel-based Virtual Machine module, HYP part
 #
 
+ccflags-y += -fno-stack-protector
+
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
index 92678b7bd046d74b2cb0ad6df34978c3a9e1c112..624a510d31df4095701387da09b4b9a27bd09a17 100644 (file)
@@ -48,7 +48,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu, u32 *fpexc_host)
        write_sysreg(HSTR_T(15), HSTR);
        write_sysreg(HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11), HCPTR);
        val = read_sysreg(HDCR);
-       write_sysreg(val | HDCR_TPM | HDCR_TPMCR, HDCR);
+       val |= HDCR_TPM | HDCR_TPMCR; /* trap performance monitors */
+       val |= HDCR_TDRA | HDCR_TDOSA | HDCR_TDA; /* trap debug regs */
+       write_sysreg(val, HDCR);
 }
 
 static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
index fc0943776db2d821a5b3931a9d4e217a8cf747d6..b0d10648c4864b22c4566884d252d2554e2ceeb6 100644 (file)
@@ -1,5 +1,5 @@
-#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_KVM_H
+#if !defined(_TRACE_ARM_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ARM_KVM_H
 
 #include <linux/tracepoint.h>
 
@@ -74,10 +74,10 @@ TRACE_EVENT(kvm_hvc,
                  __entry->vcpu_pc, __entry->r0, __entry->imm)
 );
 
-#endif /* _TRACE_KVM_H */
+#endif /* _TRACE_ARM_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH arch/arm/kvm
+#define TRACE_INCLUDE_PATH .
 #undef TRACE_INCLUDE_FILE
 #define TRACE_INCLUDE_FILE trace
 
index 2cd27c830ab68b3e7e340adb9bfab9d0e42a38ee..283e79ab587de91405e0b579fb16d202ca5072b7 100644 (file)
@@ -335,7 +335,7 @@ static const struct ramc_info ramc_infos[] __initconst = {
        { .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
 };
 
-static const struct of_device_id const ramc_ids[] __initconst = {
+static const struct of_device_id ramc_ids[] __initconst = {
        { .compatible = "atmel,at91rm9200-sdramc", .data = &ramc_infos[0] },
        { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
        { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
index cf3f8658f0e5e9849f866e2135f76aa81c11b1cc..a55a7ecf146a277df8c55603837b67d6fdc30a03 100644 (file)
@@ -33,7 +33,7 @@ struct bcm_kona_smc_data {
        unsigned result;
 };
 
-static const struct of_device_id const bcm_kona_smc_ids[] __initconst = {
+static const struct of_device_id bcm_kona_smc_ids[] __initconst = {
        {.compatible = "brcm,kona-smc"},
        {.compatible = "bcm,kona-smc"}, /* deprecated name */
        {},
index 03da3813f1ab631a0f97be7a1d893176820f9b29..7d5a44a06648de2fd8e5e15beef19762d6925e81 100644 (file)
@@ -346,7 +346,7 @@ static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
        .power_off      = csn3xxx_usb_power_off,
 };
 
-static const struct of_dev_auxdata const cns3xxx_auxdata[] __initconst = {
+static const struct of_dev_auxdata cns3xxx_auxdata[] __initconst = {
        { "intel,usb-ehci", CNS3XXX_USB_BASE, "ehci-platform", &cns3xxx_usb_ehci_pdata },
        { "intel,usb-ohci", CNS3XXX_USB_OHCI_BASE, "ohci-platform", &cns3xxx_usb_ohci_pdata },
        { "cavium,cns3420-ahci", CNS3XXX_SATA2_BASE, "ahci", NULL },
index 3089d3bfa19b4a5c595e6872824c81f103d4c5e2..8cc6338fcb1288022854d7bb3347b9e000139c76 100644 (file)
@@ -266,11 +266,12 @@ extern int omap4_cpu_kill(unsigned int cpu);
 extern const struct smp_operations omap4_smp_ops;
 #endif
 
+extern u32 omap4_get_cpu1_ns_pa_addr(void);
+
 #if defined(CONFIG_SMP) && defined(CONFIG_PM)
 extern int omap4_mpuss_init(void);
 extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
 extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
-extern u32 omap4_get_cpu1_ns_pa_addr(void);
 #else
 static inline int omap4_enter_lowpower(unsigned int cpu,
                                        unsigned int power_state)
index 03ec6d307c8235fc907a599322991b1efd6c27bf..4cfc4f9b2c6944d935d210190a0afb99b1b0c816 100644 (file)
@@ -213,11 +213,6 @@ static void __init save_l2x0_context(void)
 {}
 #endif
 
-u32 omap4_get_cpu1_ns_pa_addr(void)
-{
-       return old_cpu1_ns_pa_addr;
-}
-
 /**
  * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function
  * The purpose of this function is to manage low power programming
@@ -457,6 +452,11 @@ int __init omap4_mpuss_init(void)
 
 #endif
 
+u32 omap4_get_cpu1_ns_pa_addr(void)
+{
+       return old_cpu1_ns_pa_addr;
+}
+
 /*
  * For kexec, we must set CPU1_WAKEUP_NS_PA_ADDR to point to
  * current kernel's secondary_startup() early before
index 3faf454ba4871c8f60d5e12e912a1ff9dd9af271..33e4953c61a8843b5dde41994b30ea41c52a0abf 100644 (file)
@@ -306,7 +306,6 @@ static void __init omap4_smp_maybe_reset_cpu1(struct omap_smp_config *c)
 
        cpu1_startup_pa = readl_relaxed(cfg.wakeupgen_base +
                                        OMAP_AUX_CORE_BOOT_1);
-       cpu1_ns_pa_addr = omap4_get_cpu1_ns_pa_addr();
 
        /* Did the configured secondary_startup() get overwritten? */
        if (!omap4_smp_cpu1_startup_valid(cpu1_startup_pa))
@@ -316,9 +315,13 @@ static void __init omap4_smp_maybe_reset_cpu1(struct omap_smp_config *c)
         * If omap4 or 5 has NS_PA_ADDR configured, CPU1 may be in a
         * deeper idle state in WFI and will wake to an invalid address.
         */
-       if ((soc_is_omap44xx() || soc_is_omap54xx()) &&
-           !omap4_smp_cpu1_startup_valid(cpu1_ns_pa_addr))
-               needs_reset = true;
+       if ((soc_is_omap44xx() || soc_is_omap54xx())) {
+               cpu1_ns_pa_addr = omap4_get_cpu1_ns_pa_addr();
+               if (!omap4_smp_cpu1_startup_valid(cpu1_ns_pa_addr))
+                       needs_reset = true;
+       } else {
+               cpu1_ns_pa_addr = 0;
+       }
 
        if (!needs_reset || !c->cpu1_rstctrl_va)
                return;
index 2b138b65129a5d609ff2ae02a55181c10154113b..dc11841ca334c64aa0f70a04781463737c191282 100644 (file)
@@ -711,7 +711,7 @@ static struct omap_prcm_init_data scrm_data __initdata = {
 };
 #endif
 
-static const struct of_device_id const omap_prcm_dt_match_table[] __initconst = {
+static const struct of_device_id omap_prcm_dt_match_table[] __initconst = {
 #ifdef CONFIG_SOC_AM33XX
        { .compatible = "ti,am3-prcm", .data = &am3_prm_data },
 #endif
index 2028167fff310041cf54037798f81cc8efa9efc2..d76b1e5eb8ba50ed9a09b0e1df3c56b1e2f0c6bb 100644 (file)
@@ -559,7 +559,7 @@ struct i2c_init_data {
        u8 hsscll_12;
 };
 
-static const struct i2c_init_data const omap4_i2c_timing_data[] __initconst = {
+static const struct i2c_init_data omap4_i2c_timing_data[] __initconst = {
        {
                .load = 50,
                .loadbits = 0x3,
index 4878ba90026df68bb0d06683df795c94ee20d7ec..289e036c9c3054a3e0ba3b9d9f553867c9bd09ef 100644 (file)
@@ -204,7 +204,7 @@ static void __init spear_clockevent_init(int irq)
        setup_irq(irq, &spear_timer_irq);
 }
 
-static const struct of_device_id const timer_of_match[] __initconst = {
+static const struct of_device_id timer_of_match[] __initconst = {
        { .compatible = "st,spear-timer", },
        { },
 };
index 4afcffcb46cbf097789eb75c2bab8711647e0285..73272f43ca012faac98c0aceed350dcd49814b28 100644 (file)
@@ -106,8 +106,13 @@ config ARCH_MVEBU
        select ARMADA_AP806_SYSCON
        select ARMADA_CP110_SYSCON
        select ARMADA_37XX_CLK
+       select GPIOLIB
+       select GPIOLIB_IRQCHIP
        select MVEBU_ODMI
        select MVEBU_PIC
+       select OF_GPIO
+       select PINCTRL
+       select PINCTRL_ARMADA_37XX
        help
          This enables support for Marvell EBU familly, including:
           - Armada 3700 SoC Family
diff --git a/arch/arm64/boot/dts/include/arm b/arch/arm64/boot/dts/include/arm
deleted file mode 120000 (symlink)
index cf63d80..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../arm/boot/dts
\ No newline at end of file
diff --git a/arch/arm64/boot/dts/include/arm64 b/arch/arm64/boot/dts/include/arm64
deleted file mode 120000 (symlink)
index a96aa0e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-..
\ No newline at end of file
diff --git a/arch/arm64/boot/dts/include/dt-bindings b/arch/arm64/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
index cef5f976bc0f2afea9a85db88827c6e5529a87c4..a89855f57091fac35d3ba4b9821fd2a902f5ed77 100644 (file)
@@ -79,6 +79,8 @@
 };
 
 &i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
        status = "okay";
 
        gpio_exp: pca9555@22 {
 
 &spi0 {
        status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_quad_pins>;
 
        m25p80@0 {
                compatible = "jedec,spi-nor";
 
 /* Exported on the micro USB connector CON32 through an FTDI */
 &uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
        status = "okay";
 };
 
 };
 
 &eth0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
        phy-mode = "rgmii-id";
        phy = <&phy0>;
        status = "okay";
index 58ae9e095af2a2a986082143789995cd5cc348d7..4d495ec39202d0c34b46996598466ec87d116eea 100644 (file)
                                #clock-cells = <1>;
                        };
 
-                       gpio1: gpio@13800 {
-                               compatible = "marvell,mvebu-gpio-3700",
+                       pinctrl_nb: pinctrl@13800 {
+                               compatible = "marvell,armada3710-nb-pinctrl",
                                "syscon", "simple-mfd";
-                               reg = <0x13800 0x500>;
+                               reg = <0x13800 0x100>, <0x13C00 0x20>;
+                               gpionb: gpio {
+                                       #gpio-cells = <2>;
+                                       gpio-ranges = <&pinctrl_nb 0 0 36>;
+                                       gpio-controller;
+                                       interrupts =
+                                       <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+
+                               };
 
                                xtalclk: xtal-clk {
                                        compatible = "marvell,armada-3700-xtal-clock";
                                        clock-output-names = "xtal";
                                        #clock-cells = <0>;
                                };
+
+                               spi_quad_pins: spi-quad-pins {
+                                       groups = "spi_quad";
+                                       function = "spi";
+                               };
+
+                               i2c1_pins: i2c1-pins {
+                                       groups = "i2c1";
+                                       function = "i2c";
+                               };
+
+                               i2c2_pins: i2c2-pins {
+                                       groups = "i2c2";
+                                       function = "i2c";
+                               };
+
+                               uart1_pins: uart1-pins {
+                                       groups = "uart1";
+                                       function = "uart";
+                               };
+
+                               uart2_pins: uart2-pins {
+                                       groups = "uart2";
+                                       function = "uart";
+                               };
+                       };
+
+                       pinctrl_sb: pinctrl@18800 {
+                               compatible = "marvell,armada3710-sb-pinctrl",
+                               "syscon", "simple-mfd";
+                               reg = <0x18800 0x100>, <0x18C00 0x20>;
+                               gpiosb: gpio {
+                                       #gpio-cells = <2>;
+                                       gpio-ranges = <&pinctrl_sb 0 0 29>;
+                                       gpio-controller;
+                                       interrupts =
+                                       <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               rgmii_pins: mii-pins {
+                                       groups = "rgmii";
+                                       function = "mii";
+                               };
+
                        };
 
                        eth0: ethernet@30000 {
index 0ecaad4333a7690f68c019d660ee0bc75b8580b3..1c3634fa94bf4e7c6a65d85e9c76a6e240e4d14a 100644 (file)
        bus-width = <8>;
        max-frequency = <50000000>;
        cap-mmc-highspeed;
+       mediatek,hs200-cmd-int-delay=<26>;
+       mediatek,hs400-cmd-int-delay=<14>;
+       mediatek,hs400-cmd-resp-sel-rising;
        vmmc-supply = <&mt6397_vemc_3v3_reg>;
        vqmmc-supply = <&mt6397_vio18_reg>;
        non-removable;
index 658bb9dc9dfd3d2e1dbda080b3252fb2e2365390..7bd31066399b5859a053570a35281cec23d1d888 100644 (file)
@@ -44,7 +44,7 @@
 
 /dts-v1/;
 #include "rk3399-gru.dtsi"
-#include <include/dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/input/linux-event-codes.h>
 
 /*
  * Kevin-specific things
index ce072859e3b232dd95b9e4ca9227bb58a65161fd..65cdd878cfbd603b323a08006872f5de90e90aee 100644 (file)
@@ -30,7 +30,6 @@ CONFIG_PROFILING=y
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
@@ -62,16 +61,15 @@ CONFIG_ARCH_XGENE=y
 CONFIG_ARCH_ZX=y
 CONFIG_ARCH_ZYNQMP=y
 CONFIG_PCI=y
-CONFIG_PCI_MSI=y
 CONFIG_PCI_IOV=y
-CONFIG_PCI_AARDVARK=y
-CONFIG_PCIE_RCAR=y
-CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCI_XGENE=y
 CONFIG_PCI_LAYERSCAPE=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
+CONFIG_PCI_AARDVARK=y
+CONFIG_PCIE_RCAR=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCI_XGENE=y
 CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
 CONFIG_NUMA=y
@@ -80,12 +78,11 @@ CONFIG_KSM=y
 CONFIG_TRANSPARENT_HUGEPAGE=y
 CONFIG_CMA=y
 CONFIG_SECCOMP=y
-CONFIG_XEN=y
 CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
+CONFIG_XEN=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_COMPAT=y
-CONFIG_CPU_IDLE=y
 CONFIG_HIBERNATION=y
 CONFIG_ARM_CPUIDLE=y
 CONFIG_CPU_FREQ=y
@@ -155,8 +152,8 @@ CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
-CONFIG_EEPROM_AT25=m
 CONFIG_SRAM=y
+CONFIG_EEPROM_AT25=m
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SAS_ATA=y
@@ -168,8 +165,8 @@ CONFIG_AHCI_CEVA=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_AHCI_XGENE=y
 CONFIG_AHCI_QORIQ=y
-CONFIG_SATA_RCAR=y
 CONFIG_SATA_SIL24=y
+CONFIG_SATA_RCAR=y
 CONFIG_PATA_PLATFORM=y
 CONFIG_PATA_OF_PLATFORM=y
 CONFIG_NETDEVICES=y
@@ -186,18 +183,17 @@ CONFIG_HNS_ENET=y
 CONFIG_E1000E=y
 CONFIG_IGB=y
 CONFIG_IGBVF=y
-CONFIG_MVPP2=y
 CONFIG_MVNETA=y
+CONFIG_MVPP2=y
 CONFIG_SKY2=y
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
 CONFIG_STMMAC_ETH=m
-CONFIG_REALTEK_PHY=m
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
-CONFIG_MDIO_BUS_MUX=y
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_REALTEK_PHY=m
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
@@ -230,14 +226,14 @@ CONFIG_SERIAL_8250_UNIPHIER=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MESON=y
+CONFIG_SERIAL_MESON_CONSOLE=y
 CONFIG_SERIAL_SAMSUNG=y
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_TEGRA=y
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=11
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
-CONFIG_SERIAL_MESON=y
-CONFIG_SERIAL_MESON_CONSOLE=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_XILINX_PS_UART=y
@@ -261,14 +257,14 @@ CONFIG_I2C_UNIPHIER_F=y
 CONFIG_I2C_RCAR=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SPI=y
-CONFIG_SPI_MESON_SPIFC=m
 CONFIG_SPI_BCM2835=m
 CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_MESON_SPIFC=m
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_QUP=y
-CONFIG_SPI_SPIDEV=m
 CONFIG_SPI_S3C64XX=y
+CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_MAX77620=y
@@ -286,33 +282,30 @@ CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_MAX77620=y
 CONFIG_POWER_RESET_MSM=y
-CONFIG_BATTERY_BQ27XXX=y
 CONFIG_POWER_RESET_XGENE=y
 CONFIG_POWER_RESET_SYSCON=y
+CONFIG_BATTERY_BQ27XXX=y
+CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_INA2XX=m
-CONFIG_SENSORS_ARM_SCPI=y
-CONFIG_THERMAL=y
-CONFIG_THERMAL_EMULATION=y
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
-CONFIG_BCM2835_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_WATCHDOG=y
-CONFIG_BCM2835_WDT=y
-CONFIG_RENESAS_WDT=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
+CONFIG_RENESAS_WDT=y
+CONFIG_BCM2835_WDT=y
+CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_I2C=y
 CONFIG_MFD_EXYNOS_LPASS=m
+CONFIG_MFD_HI655X_PMIC=y
 CONFIG_MFD_MAX77620=y
-CONFIG_MFD_RK808=y
 CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_RK808=y
 CONFIG_MFD_SEC_CORE=y
-CONFIG_MFD_HI655X_PMIC=y
-CONFIG_REGULATOR=y
-CONFIG_MFD_CROS_EC=y
-CONFIG_MFD_CROS_EC_I2C=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_HI655X=y
@@ -345,13 +338,12 @@ CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_EXYNOS_MIC=y
 CONFIG_DRM_RCAR_DU=m
-CONFIG_DRM_RCAR_HDMI=y
 CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_RCAR_VSP=y
 CONFIG_DRM_TEGRA=m
-CONFIG_DRM_VC4=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_VC4=m
 CONFIG_DRM_HISI_KIRIN=m
 CONFIG_DRM_MESON=m
 CONFIG_FB=y
@@ -366,39 +358,37 @@ CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
-CONFIG_SND_SOC_RCAR=y
 CONFIG_SND_SOC_SAMSUNG=y
+CONFIG_SND_SOC_RCAR=y
 CONFIG_SND_SOC_AK4613=y
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USB_XHCI_RCAR=y
-CONFIG_USB_EHCI_EXYNOS=y
 CONFIG_USB_XHCI_TEGRA=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_EHCI_EXYNOS=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_EXYNOS=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_EXYNOS=y
 CONFIG_USB_OHCI_HCD_PLATFORM=y
 CONFIG_USB_RENESAS_USBHS=m
 CONFIG_USB_STORAGE=y
-CONFIG_USB_DWC2=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_USB_ISP1760=y
 CONFIG_USB_HSIC_USB3503=y
 CONFIG_USB_MSM_OTG=y
+CONFIG_USB_QCOM_8X16_PHY=y
 CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_ARMMMCI=y
-CONFIG_MMC_MESON_GX=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ACPI=y
 CONFIG_MMC_SDHCI_PLTFM=y
@@ -406,6 +396,7 @@ CONFIG_MMC_SDHCI_OF_ARASAN=y
 CONFIG_MMC_SDHCI_OF_ESDHC=y
 CONFIG_MMC_SDHCI_CADENCE=y
 CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_MMC_MESON_GX=y
 CONFIG_MMC_SDHCI_MSM=y
 CONFIG_MMC_SPI=y
 CONFIG_MMC_SDHI=y
@@ -414,32 +405,31 @@ CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_K3=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SUNXI=y
-CONFIG_MMC_SDHCI_XENON=y
 CONFIG_MMC_BCM2835=y
+CONFIG_MMC_SDHCI_XENON=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_PWM=y
 CONFIG_LEDS_SYSCON=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX77686=y
+CONFIG_RTC_DRV_RK808=m
 CONFIG_RTC_DRV_S5M=y
 CONFIG_RTC_DRV_DS3232=y
 CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_S3C=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_SUN6I=y
-CONFIG_RTC_DRV_RK808=m
 CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_DRV_XGENE=y
-CONFIG_RTC_DRV_S3C=y
 CONFIG_DMADEVICES=y
+CONFIG_DMA_BCM2835=m
 CONFIG_MV_XOR_V2=y
 CONFIG_PL330_DMA=y
-CONFIG_DMA_BCM2835=m
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_QCOM_HIDMA_MGMT=y
@@ -452,52 +442,53 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_COMMON_CLK_RK808=y
 CONFIG_COMMON_CLK_SCPI=y
 CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_S2MPS11=y
-CONFIG_COMMON_CLK_PWM=y
-CONFIG_COMMON_CLK_RK808=y
 CONFIG_CLK_QORIQ=y
+CONFIG_COMMON_CLK_PWM=y
 CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_MSM_GCC_8916=y
 CONFIG_MSM_GCC_8994=y
 CONFIG_MSM_MMCC_8996=y
 CONFIG_HWSPINLOCK_QCOM=y
-CONFIG_MAILBOX=y
 CONFIG_ARM_MHU=y
 CONFIG_PLATFORM_MHU=y
 CONFIG_BCM2835_MBOX=y
 CONFIG_HI6220_MBOX=y
 CONFIG_ARM_SMMU=y
 CONFIG_ARM_SMMU_V3=y
+CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_RASPBERRYPI_POWER=y
 CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
 CONFIG_ARCH_TEGRA_186_SOC=y
 CONFIG_EXTCON_USB_GPIO=y
+CONFIG_IIO=y
+CONFIG_EXYNOS_ADC=y
 CONFIG_PWM=y
 CONFIG_PWM_BCM2835=m
+CONFIG_PWM_MESON=m
 CONFIG_PWM_ROCKCHIP=y
+CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_TEGRA=m
-CONFIG_PWM_MESON=m
-CONFIG_COMMON_RESET_HI6220=y
 CONFIG_PHY_RCAR_GEN3_USB2=y
 CONFIG_PHY_HI6220_USB=y
+CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_EMMC=y
-CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_ACPI=y
-CONFIG_IIO=y
-CONFIG_EXYNOS_ADC=y
-CONFIG_PWM_SAMSUNG=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_ACPI=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
@@ -511,7 +502,6 @@ CONFIG_FUSE_FS=m
 CONFIG_CUSE=m
 CONFIG_OVERLAY_FS=m
 CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
@@ -539,11 +529,9 @@ CONFIG_MEMTEST=y
 CONFIG_SECURITY=y
 CONFIG_CRYPTO_ECHAINIV=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
-CONFIG_CRYPTO_DEV_SAFEXCEL=m
 CONFIG_ARM64_CRYPTO=y
 CONFIG_CRYPTO_SHA1_ARM64_CE=y
 CONFIG_CRYPTO_SHA2_ARM64_CE=y
 CONFIG_CRYPTO_GHASH_ARM64_CE=y
 CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
 CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
-# CONFIG_CRYPTO_AES_ARM64_NEON_BLK is not set
index f819fdcff1accf694cc0ec7428096fe41aef7f89..f5a2d09afb3841bd5ac7d40764ef48b2e108de0d 100644 (file)
@@ -264,7 +264,6 @@ __LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr,            \
        "       st" #rel "xr" #sz "\t%w[tmp], %" #w "[new], %[v]\n"     \
        "       cbnz    %w[tmp], 1b\n"                                  \
        "       " #mb "\n"                                              \
-       "       mov     %" #w "[oldval], %" #w "[old]\n"                \
        "2:"                                                            \
        : [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),                   \
          [v] "+Q" (*(unsigned long *)ptr)                              \
index e7f84a7b44658d2f93d642e06e013300693d6a82..428ee1f2468c55959d52cf1cffde922399387b9f 100644 (file)
@@ -115,6 +115,7 @@ struct arm64_cpu_capabilities {
 
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
+extern struct static_key_false arm64_const_caps_ready;
 
 bool this_cpu_has_cap(unsigned int cap);
 
@@ -124,7 +125,7 @@ static inline bool cpu_have_feature(unsigned int num)
 }
 
 /* System capability check for constant caps */
-static inline bool cpus_have_const_cap(int num)
+static inline bool __cpus_have_const_cap(int num)
 {
        if (num >= ARM64_NCAPS)
                return false;
@@ -138,6 +139,14 @@ static inline bool cpus_have_cap(unsigned int num)
        return test_bit(num, cpu_hwcaps);
 }
 
+static inline bool cpus_have_const_cap(int num)
+{
+       if (static_branch_likely(&arm64_const_caps_ready))
+               return __cpus_have_const_cap(num);
+       else
+               return cpus_have_cap(num);
+}
+
 static inline void cpus_set_cap(unsigned int num)
 {
        if (num >= ARM64_NCAPS) {
@@ -145,7 +154,6 @@ static inline void cpus_set_cap(unsigned int num)
                        num, ARM64_NCAPS);
        } else {
                __set_bit(num, cpu_hwcaps);
-               static_branch_enable(&cpu_hwcap_keys[num]);
        }
 }
 
index 5e19165c5fa8b86002f0308812a0c49199a91b44..1f252a95bc02979cc8c6f01425e26e44f34c1990 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/types.h>
 #include <linux/kvm_types.h>
+#include <asm/cpufeature.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmio.h>
@@ -355,9 +356,12 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
                                       unsigned long vector_ptr)
 {
        /*
-        * Call initialization code, and switch to the full blown
-        * HYP code.
+        * Call initialization code, and switch to the full blown HYP code.
+        * If the cpucaps haven't been finalized yet, something has gone very
+        * wrong, and hyp will crash and burn when it uses any
+        * cpus_have_const_cap() wrapper.
         */
+       BUG_ON(!static_branch_likely(&arm64_const_caps_ready));
        __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
index 94b8f7fc33100f85db825a372bf36d6f597934ac..817ce3365e200dfb5f7ff205dadabe72c3490e43 100644 (file)
@@ -985,8 +985,16 @@ void update_cpu_capabilities(const struct arm64_cpu_capabilities *caps,
  */
 void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
 {
-       for (; caps->matches; caps++)
-               if (caps->enable && cpus_have_cap(caps->capability))
+       for (; caps->matches; caps++) {
+               unsigned int num = caps->capability;
+
+               if (!cpus_have_cap(num))
+                       continue;
+
+               /* Ensure cpus_have_const_cap(num) works */
+               static_branch_enable(&cpu_hwcap_keys[num]);
+
+               if (caps->enable) {
                        /*
                         * Use stop_machine() as it schedules the work allowing
                         * us to modify PSTATE, instead of on_each_cpu() which
@@ -994,6 +1002,8 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
                         * we return.
                         */
                        stop_machine(caps->enable, NULL, cpu_online_mask);
+               }
+       }
 }
 
 /*
@@ -1096,6 +1106,14 @@ static void __init setup_feature_capabilities(void)
        enable_cpu_capabilities(arm64_features);
 }
 
+DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready);
+EXPORT_SYMBOL(arm64_const_caps_ready);
+
+static void __init mark_const_caps_ready(void)
+{
+       static_branch_enable(&arm64_const_caps_ready);
+}
+
 /*
  * Check if the current CPU has a given feature capability.
  * Should be called from non-preemptible context.
@@ -1131,6 +1149,7 @@ void __init setup_cpu_features(void)
        /* Set the CPU feature capabilies */
        setup_feature_capabilities();
        enable_errata_workarounds();
+       mark_const_caps_ready();
        setup_elf_hwcaps(arm64_elf_hwcaps);
 
        if (system_supports_32bit_el0())
index bcc79471b38e24cff24b5702a182752ef26583cc..83a1b1ad189f51536af8c4c8dd8c509cb70f9a95 100644 (file)
@@ -877,15 +877,24 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event,
 
        if (attr->exclude_idle)
                return -EPERM;
-       if (is_kernel_in_hyp_mode() &&
-           attr->exclude_kernel != attr->exclude_hv)
-               return -EINVAL;
+
+       /*
+        * If we're running in hyp mode, then we *are* the hypervisor.
+        * Therefore we ignore exclude_hv in this configuration, since
+        * there's no hypervisor to sample anyway. This is consistent
+        * with other architectures (x86 and Power).
+        */
+       if (is_kernel_in_hyp_mode()) {
+               if (!attr->exclude_kernel)
+                       config_base |= ARMV8_PMU_INCLUDE_EL2;
+       } else {
+               if (attr->exclude_kernel)
+                       config_base |= ARMV8_PMU_EXCLUDE_EL1;
+               if (!attr->exclude_hv)
+                       config_base |= ARMV8_PMU_INCLUDE_EL2;
+       }
        if (attr->exclude_user)
                config_base |= ARMV8_PMU_EXCLUDE_EL0;
-       if (!is_kernel_in_hyp_mode() && attr->exclude_kernel)
-               config_base |= ARMV8_PMU_EXCLUDE_EL1;
-       if (!attr->exclude_hv)
-               config_base |= ARMV8_PMU_INCLUDE_EL2;
 
        /*
         * Install the filter into config_base as this is used to
index aaf42ae8d8c31395d63590289e55798073bc99a4..14c4e3b14bcb6f59a6de55db07de9cc8457be8ec 100644 (file)
@@ -2,6 +2,8 @@
 # Makefile for Kernel-based Virtual Machine module, HYP part
 #
 
+ccflags-y += -fno-stack-protector
+
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
index c6e53580aefe9148f6d865a9a89e611a6d1c542e..71f930501ade7cec2d1f230aa638ad3fc9112ee8 100644 (file)
@@ -253,8 +253,9 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
         */
        off = offsetof(struct bpf_array, ptrs);
        emit_a64_mov_i64(tmp, off, ctx);
-       emit(A64_LDR64(tmp, r2, tmp), ctx);
-       emit(A64_LDR64(prg, tmp, r3), ctx);
+       emit(A64_ADD(1, tmp, r2, tmp), ctx);
+       emit(A64_LSL(1, prg, r3, 3), ctx);
+       emit(A64_LDR64(prg, tmp, prg), ctx);
        emit(A64_CBZ(1, prg, jmp_offset), ctx);
 
        /* goto *(prog->bpf_func + prologue_size); */
diff --git a/arch/cris/boot/dts/include/dt-bindings b/arch/cris/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/arch/metag/boot/dts/include/dt-bindings b/arch/metag/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/arch/mips/boot/dts/include/dt-bindings b/arch/mips/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/arch/powerpc/boot/dts/include/dt-bindings b/arch/powerpc/boot/dts/include/dt-bindings
deleted file mode 120000 (symlink)
index 08c00e4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../include/dt-bindings
\ No newline at end of file
index 53885512b8d31b12acec28dc3ba6688e57fb9615..6c0132c7212f8ea484805c9a9f72b682b79f6a39 100644 (file)
 #include <asm-generic/module.h>
 
 
+#ifdef CC_USING_MPROFILE_KERNEL
+#define MODULE_ARCH_VERMAGIC   "mprofile-kernel"
+#endif
+
 #ifndef __powerpc64__
 /*
  * Thanks to Paul M for explaining this.
index 2a32483c7b6cd5db8bab609891a5fbb3ad1f7844..8da5d4c1cab2b6d52a297117c6e6b27221d941c6 100644 (file)
@@ -132,7 +132,19 @@ extern long long virt_phys_offset;
 #define virt_to_pfn(kaddr)     (__pa(kaddr) >> PAGE_SHIFT)
 #define virt_to_page(kaddr)    pfn_to_page(virt_to_pfn(kaddr))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
+
+#ifdef CONFIG_PPC_BOOK3S_64
+/*
+ * On hash the vmalloc and other regions alias to the kernel region when passed
+ * through __pa(), which virt_to_pfn() uses. That means virt_addr_valid() can
+ * return true for some vmalloc addresses, which is incorrect. So explicitly
+ * check that the address is in the kernel region.
+ */
+#define virt_addr_valid(kaddr) (REGION_ID(kaddr) == KERNEL_REGION_ID && \
+                               pfn_valid(virt_to_pfn(kaddr)))
+#else
 #define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr))
+#endif
 
 /*
  * On Book-E parts we need __va to parse the device tree and we can't
index 07d4e0ad60db5b1a1f2cd5da08763a3acea7ea3b..4898d676dcaef1d02600c5c75ef13ceca1fc8c69 100644 (file)
@@ -416,7 +416,7 @@ power9_dd1_recover_paca:
         * which needs to be restored from the stack.
         */
        li      r3, 1
-       stb     r0,PACA_NAPSTATELOST(r13)
+       stb     r3,PACA_NAPSTATELOST(r13)
        blr
 
 /*
index 160ae0fa7d0d15152011b111134784107287e7bb..fc4343514bed8b0f05a88e64caf0285c44ee8ea0 100644 (file)
@@ -305,16 +305,17 @@ int kprobe_handler(struct pt_regs *regs)
                        save_previous_kprobe(kcb);
                        set_current_kprobe(p, regs, kcb);
                        kprobes_inc_nmissed_count(p);
-                       prepare_singlestep(p, regs);
                        kcb->kprobe_status = KPROBE_REENTER;
                        if (p->ainsn.boostable >= 0) {
                                ret = try_to_emulate(p, regs);
 
                                if (ret > 0) {
                                        restore_previous_kprobe(kcb);
+                                       preempt_enable_no_resched();
                                        return 1;
                                }
                        }
+                       prepare_singlestep(p, regs);
                        return 1;
                } else {
                        if (*addr != BREAKPOINT_INSTRUCTION) {
index d645da302bf22f46c046bcb3912bbdd51186c416..baae104b16c7ba9f7cdf4a305ab5227ebf002467 100644 (file)
@@ -864,6 +864,25 @@ static void tm_reclaim_thread(struct thread_struct *thr,
        if (!MSR_TM_SUSPENDED(mfmsr()))
                return;
 
+       /*
+        * If we are in a transaction and FP is off then we can't have
+        * used FP inside that transaction. Hence the checkpointed
+        * state is the same as the live state. We need to copy the
+        * live state to the checkpointed state so that when the
+        * transaction is restored, the checkpointed state is correct
+        * and the aborted transaction sees the correct state. We use
+        * ckpt_regs.msr here as that's what tm_reclaim will use to
+        * determine if it's going to write the checkpointed state or
+        * not. So either this will write the checkpointed registers,
+        * or reclaim will. Similarly for VMX.
+        */
+       if ((thr->ckpt_regs.msr & MSR_FP) == 0)
+               memcpy(&thr->ckfp_state, &thr->fp_state,
+                      sizeof(struct thread_fp_state));
+       if ((thr->ckpt_regs.msr & MSR_VEC) == 0)
+               memcpy(&thr->ckvr_state, &thr->vr_state,
+                      sizeof(struct thread_vr_state));
+
        giveup_all(container_of(thr, struct task_struct, thread));
 
        tm_reclaim(thr, thr->ckpt_regs.msr, cause);
index 24de532c17369c1d8fb9498c50447cc6c6b21528..0c52cb5d43f52bdba5008ccade5edfd2b4fee5f4 100644 (file)
@@ -67,7 +67,7 @@ config KVM_BOOK3S_64
        select KVM_BOOK3S_64_HANDLER
        select KVM
        select KVM_BOOK3S_PR_POSSIBLE if !KVM_BOOK3S_HV_POSSIBLE
-       select SPAPR_TCE_IOMMU if IOMMU_SUPPORT
+       select SPAPR_TCE_IOMMU if IOMMU_SUPPORT && (PPC_SERIES || PPC_POWERNV)
        ---help---
          Support running unmodified book3s_64 and book3s_32 guest kernels
          in virtual machines on book3s_64 host processors.
index d91a2604c49637c009f6a8ef42b69821dcbc445d..381a6ec0ff3b72ab085834fc14a35e853b237fc6 100644 (file)
@@ -46,7 +46,7 @@ kvm-e500mc-objs := \
        e500_emulate.o
 kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
 
-kvm-book3s_64-builtin-objs-$(CONFIG_KVM_BOOK3S_64_HANDLER) := \
+kvm-book3s_64-builtin-objs-$(CONFIG_SPAPR_TCE_IOMMU) := \
        book3s_64_vio_hv.o
 
 kvm-pr-y := \
@@ -90,11 +90,11 @@ kvm-book3s_64-objs-$(CONFIG_KVM_XICS) += \
        book3s_xics.o
 
 kvm-book3s_64-objs-$(CONFIG_KVM_XIVE) += book3s_xive.o
+kvm-book3s_64-objs-$(CONFIG_SPAPR_TCE_IOMMU) += book3s_64_vio.o
 
 kvm-book3s_64-module-objs := \
        $(common-objs-y) \
        book3s.o \
-       book3s_64_vio.o \
        book3s_rtas.o \
        $(kvm-book3s_64-objs-y)
 
index eda0a8f6fae8eba29b5b04c28fe49e7f9d605d45..3adfd2f5301c686762007e496717d453c258d37c 100644 (file)
@@ -301,6 +301,10 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
        /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
        /*          liobn, ioba, tce); */
 
+       /* For radix, we might be in virtual mode, so punt */
+       if (kvm_is_radix(vcpu->kvm))
+               return H_TOO_HARD;
+
        stt = kvmppc_find_table(vcpu->kvm, liobn);
        if (!stt)
                return H_TOO_HARD;
@@ -381,6 +385,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
        bool prereg = false;
        struct kvmppc_spapr_tce_iommu_table *stit;
 
+       /* For radix, we might be in virtual mode, so punt */
+       if (kvm_is_radix(vcpu->kvm))
+               return H_TOO_HARD;
+
        stt = kvmppc_find_table(vcpu->kvm, liobn);
        if (!stt)
                return H_TOO_HARD;
@@ -491,6 +499,10 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
        long i, ret;
        struct kvmppc_spapr_tce_iommu_table *stit;
 
+       /* For radix, we might be in virtual mode, so punt */
+       if (kvm_is_radix(vcpu->kvm))
+               return H_TOO_HARD;
+
        stt = kvmppc_find_table(vcpu->kvm, liobn);
        if (!stt)
                return H_TOO_HARD;
@@ -527,6 +539,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
        return H_SUCCESS;
 }
 
+/* This can be called in either virtual mode or real mode */
 long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
                      unsigned long ioba)
 {
index 88a65923c6495750db570890954f65416e359d25..ee4c2558c3058717da1f6299fd6a0e0aebc75360 100644 (file)
@@ -207,7 +207,14 @@ EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);
 
 long kvmppc_h_random(struct kvm_vcpu *vcpu)
 {
-       if (powernv_get_random_real_mode(&vcpu->arch.gpr[4]))
+       int r;
+
+       /* Only need to do the expensive mfmsr() on radix */
+       if (kvm_is_radix(vcpu->kvm) && (mfmsr() & MSR_IR))
+               r = powernv_get_random_long(&vcpu->arch.gpr[4]);
+       else
+               r = powernv_get_random_real_mode(&vcpu->arch.gpr[4]);
+       if (r)
                return H_SUCCESS;
 
        return H_HARDWARE;
index bcbeeb62dd13e9eafb9d0b8e4c6ece982627db85..8a4205fa774fe552a8a7f72b90b9c28dfb1ed0e5 100644 (file)
@@ -50,7 +50,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu)
        pteg_addr = get_pteg_addr(vcpu, pte_index);
 
        mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-       copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg));
+       ret = H_FUNCTION;
+       if (copy_from_user(pteg, (void __user *)pteg_addr, sizeof(pteg)))
+               goto done;
        hpte = pteg;
 
        ret = H_PTEG_FULL;
@@ -71,7 +73,9 @@ static int kvmppc_h_pr_enter(struct kvm_vcpu *vcpu)
        hpte[0] = cpu_to_be64(kvmppc_get_gpr(vcpu, 6));
        hpte[1] = cpu_to_be64(kvmppc_get_gpr(vcpu, 7));
        pteg_addr += i * HPTE_SIZE;
-       copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE);
+       ret = H_FUNCTION;
+       if (copy_to_user((void __user *)pteg_addr, hpte, HPTE_SIZE))
+               goto done;
        kvmppc_set_gpr(vcpu, 4, pte_index | i);
        ret = H_SUCCESS;
 
@@ -93,7 +97,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu)
 
        pteg = get_pteg_addr(vcpu, pte_index);
        mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-       copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+       ret = H_FUNCTION;
+       if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
+               goto done;
        pte[0] = be64_to_cpu((__force __be64)pte[0]);
        pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -103,7 +109,9 @@ static int kvmppc_h_pr_remove(struct kvm_vcpu *vcpu)
            ((flags & H_ANDCOND) && (pte[0] & avpn) != 0))
                goto done;
 
-       copy_to_user((void __user *)pteg, &v, sizeof(v));
+       ret = H_FUNCTION;
+       if (copy_to_user((void __user *)pteg, &v, sizeof(v)))
+               goto done;
 
        rb = compute_tlbie_rb(pte[0], pte[1], pte_index);
        vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
@@ -171,7 +179,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu)
                }
 
                pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX);
-               copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+               if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) {
+                       ret = H_FUNCTION;
+                       break;
+               }
                pte[0] = be64_to_cpu((__force __be64)pte[0]);
                pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -184,7 +195,10 @@ static int kvmppc_h_pr_bulk_remove(struct kvm_vcpu *vcpu)
                        tsh |= H_BULK_REMOVE_NOT_FOUND;
                } else {
                        /* Splat the pteg in (userland) hpt */
-                       copy_to_user((void __user *)pteg, &v, sizeof(v));
+                       if (copy_to_user((void __user *)pteg, &v, sizeof(v))) {
+                               ret = H_FUNCTION;
+                               break;
+                       }
 
                        rb = compute_tlbie_rb(pte[0], pte[1],
                                              tsh & H_BULK_REMOVE_PTEX);
@@ -211,7 +225,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
 
        pteg = get_pteg_addr(vcpu, pte_index);
        mutex_lock(&vcpu->kvm->arch.hpt_mutex);
-       copy_from_user(pte, (void __user *)pteg, sizeof(pte));
+       ret = H_FUNCTION;
+       if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
+               goto done;
        pte[0] = be64_to_cpu((__force __be64)pte[0]);
        pte[1] = be64_to_cpu((__force __be64)pte[1]);
 
@@ -234,7 +250,9 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
        vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
        pte[0] = (__force u64)cpu_to_be64(pte[0]);
        pte[1] = (__force u64)cpu_to_be64(pte[1]);
-       copy_to_user((void __user *)pteg, pte, sizeof(pte));
+       ret = H_FUNCTION;
+       if (copy_to_user((void __user *)pteg, pte, sizeof(pte)))
+               goto done;
        ret = H_SUCCESS;
 
  done:
@@ -244,36 +262,37 @@ static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
        return EMULATE_DONE;
 }
 
-static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
+static int kvmppc_h_pr_logical_ci_load(struct kvm_vcpu *vcpu)
 {
-       unsigned long liobn = kvmppc_get_gpr(vcpu, 4);
-       unsigned long ioba = kvmppc_get_gpr(vcpu, 5);
-       unsigned long tce = kvmppc_get_gpr(vcpu, 6);
        long rc;
 
-       rc = kvmppc_h_put_tce(vcpu, liobn, ioba, tce);
+       rc = kvmppc_h_logical_ci_load(vcpu);
        if (rc == H_TOO_HARD)
                return EMULATE_FAIL;
        kvmppc_set_gpr(vcpu, 3, rc);
        return EMULATE_DONE;
 }
 
-static int kvmppc_h_pr_logical_ci_load(struct kvm_vcpu *vcpu)
+static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
 {
        long rc;
 
-       rc = kvmppc_h_logical_ci_load(vcpu);
+       rc = kvmppc_h_logical_ci_store(vcpu);
        if (rc == H_TOO_HARD)
                return EMULATE_FAIL;
        kvmppc_set_gpr(vcpu, 3, rc);
        return EMULATE_DONE;
 }
 
-static int kvmppc_h_pr_logical_ci_store(struct kvm_vcpu *vcpu)
+#ifdef CONFIG_SPAPR_TCE_IOMMU
+static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
 {
+       unsigned long liobn = kvmppc_get_gpr(vcpu, 4);
+       unsigned long ioba = kvmppc_get_gpr(vcpu, 5);
+       unsigned long tce = kvmppc_get_gpr(vcpu, 6);
        long rc;
 
-       rc = kvmppc_h_logical_ci_store(vcpu);
+       rc = kvmppc_h_put_tce(vcpu, liobn, ioba, tce);
        if (rc == H_TOO_HARD)
                return EMULATE_FAIL;
        kvmppc_set_gpr(vcpu, 3, rc);
@@ -311,6 +330,23 @@ static int kvmppc_h_pr_stuff_tce(struct kvm_vcpu *vcpu)
        return EMULATE_DONE;
 }
 
+#else /* CONFIG_SPAPR_TCE_IOMMU */
+static int kvmppc_h_pr_put_tce(struct kvm_vcpu *vcpu)
+{
+       return EMULATE_FAIL;
+}
+
+static int kvmppc_h_pr_put_tce_indirect(struct kvm_vcpu *vcpu)
+{
+       return EMULATE_FAIL;
+}
+
+static int kvmppc_h_pr_stuff_tce(struct kvm_vcpu *vcpu)
+{
+       return EMULATE_FAIL;
+}
+#endif /* CONFIG_SPAPR_TCE_IOMMU */
+
 static int kvmppc_h_pr_xics_hcall(struct kvm_vcpu *vcpu, u32 cmd)
 {
        long rc = kvmppc_xics_hcall(vcpu, cmd);
index f7cf2cd564efe53a072b91cb3705e69a0ffa6e02..7f71ab5fcad1bbc20abaa43627c1220c3ff4e17b 100644 (file)
@@ -1749,7 +1749,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
                r = kvm_vm_ioctl_enable_cap(kvm, &cap);
                break;
        }
-#ifdef CONFIG_PPC_BOOK3S_64
+#ifdef CONFIG_SPAPR_TCE_IOMMU
        case KVM_CREATE_SPAPR_TCE_64: {
                struct kvm_create_spapr_tce_64 create_tce_64;
 
@@ -1780,6 +1780,8 @@ long kvm_arch_vm_ioctl(struct file *filp,
                r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
                goto out;
        }
+#endif
+#ifdef CONFIG_PPC_BOOK3S_64
        case KVM_PPC_GET_SMMU_INFO: {
                struct kvm_ppc_smmu_info info;
                struct kvm *kvm = filp->private_data;
index d659345a98d66c03a2cab1ceed3526af95551cc6..44fe4833910f64bcd014a2e3843ecd8c3077fc26 100644 (file)
@@ -16,6 +16,7 @@
  */
 #include <linux/debugfs.h>
 #include <linux/fs.h>
+#include <linux/hugetlb.h>
 #include <linux/io.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
@@ -391,7 +392,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start)
 
        for (i = 0; i < PTRS_PER_PMD; i++, pmd++) {
                addr = start + i * PMD_SIZE;
-               if (!pmd_none(*pmd))
+               if (!pmd_none(*pmd) && !pmd_huge(*pmd))
                        /* pmd exists */
                        walk_pte(st, pmd, addr);
                else
@@ -407,7 +408,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
 
        for (i = 0; i < PTRS_PER_PUD; i++, pud++) {
                addr = start + i * PUD_SIZE;
-               if (!pud_none(*pud))
+               if (!pud_none(*pud) && !pud_huge(*pud))
                        /* pud exists */
                        walk_pmd(st, pud, addr);
                else
@@ -427,7 +428,7 @@ static void walk_pagetables(struct pg_state *st)
         */
        for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
                addr = KERN_VIRT_START + i * PGDIR_SIZE;
-               if (!pgd_none(*pgd))
+               if (!pgd_none(*pgd) && !pgd_huge(*pgd))
                        /* pgd exists */
                        walk_pud(st, pgd, addr);
                else
index 0206c805232878c95a6588dbb9909ecb4268d5d0..df7b54ea956daeb6c9a1091518e73417e688e504 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
+#include <linux/refcount.h>
 #include <uapi/asm/debug.h>
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
@@ -31,7 +32,7 @@ struct debug_view;
 typedef struct debug_info {    
        struct debug_info* next;
        struct debug_info* prev;
-       atomic_t ref_count;
+       refcount_t ref_count;
        spinlock_t lock;                        
        int level;
        int nr_areas;
index 60323c21938bb5d97407e9f0cb35c6fcdd335597..37f617dfbeded0de8edb9f9f4e1a263c46bd0635 100644 (file)
@@ -40,6 +40,8 @@ static inline int insn_length(unsigned char code)
        return ((((int) code + 64) >> 7) + 1) << 1;
 }
 
+struct pt_regs;
+
 void show_code(struct pt_regs *regs);
 void print_fn_code(unsigned char *code, unsigned long len);
 int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len);
index 1293c4066cfc806f96f06bec93743f7d051f2973..28792ef82c837a2f2c11a5765098434018d02598 100644 (file)
  * 2005-Dec    Used as a template for s390 by Mike Grundy
  *             <grundym@us.ibm.com>
  */
+#include <linux/types.h>
 #include <asm-generic/kprobes.h>
 
 #define BREAKPOINT_INSTRUCTION 0x0002
 
+#define FIXUP_PSW_NORMAL       0x08
+#define FIXUP_BRANCH_NOT_TAKEN 0x04
+#define FIXUP_RETURN_REGISTER  0x02
+#define FIXUP_NOT_REQUIRED     0x01
+
+int probe_is_prohibited_opcode(u16 *insn);
+int probe_get_fixup_type(u16 *insn);
+int probe_is_insn_relative_long(u16 *insn);
+
 #ifdef CONFIG_KPROBES
-#include <linux/types.h>
 #include <linux/ptrace.h>
 #include <linux/percpu.h>
 #include <linux/sched/task_stack.h>
@@ -56,11 +65,6 @@ typedef u16 kprobe_opcode_t;
 
 #define KPROBE_SWAP_INST       0x10
 
-#define FIXUP_PSW_NORMAL       0x08
-#define FIXUP_BRANCH_NOT_TAKEN 0x04
-#define FIXUP_RETURN_REGISTER  0x02
-#define FIXUP_NOT_REQUIRED     0x01
-
 /* Architecture specific copy of original instruction */
 struct arch_specific_insn {
        /* copy of original instruction */
@@ -90,10 +94,6 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 int kprobe_exceptions_notify(struct notifier_block *self,
        unsigned long val, void *data);
 
-int probe_is_prohibited_opcode(u16 *insn);
-int probe_get_fixup_type(u16 *insn);
-int probe_is_insn_relative_long(u16 *insn);
-
 #define flush_insn_slot(p)     do { } while (0)
 
 #endif /* CONFIG_KPROBES */
index 73bff45ced55268c7f06e52a98be46f7eaa2ea54..e784bed6ed7ffb24cabb02eb92a1d90494e3b7e1 100644 (file)
@@ -146,7 +146,7 @@ extern int topology_max_mnest;
  * Returns the maximum nesting level supported by the cpu topology code.
  * The current maximum level is 4 which is the drawer level.
  */
-static inline int topology_mnest_limit(void)
+static inline unsigned char topology_mnest_limit(void)
 {
        return min(topology_max_mnest, 4);
 }
index 530226b6cb19a2ed5bb011ab61215f69e243d4c5..86b3e74f569eb7823ba6c4b0c4ec7baeb456e2f1 100644 (file)
@@ -277,7 +277,7 @@ debug_info_alloc(const char *name, int pages_per_area, int nr_areas,
        memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
        memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS *
                sizeof(struct dentry*));
-       atomic_set(&(rc->ref_count), 0);
+       refcount_set(&(rc->ref_count), 0);
 
        return rc;
 
@@ -361,7 +361,7 @@ debug_info_create(const char *name, int pages_per_area, int nr_areas,
         debug_area_last = rc;
         rc->next = NULL;
 
-       debug_info_get(rc);
+       refcount_set(&rc->ref_count, 1);
 out:
        return rc;
 }
@@ -416,7 +416,7 @@ static void
 debug_info_get(debug_info_t * db_info)
 {
        if (db_info)
-               atomic_inc(&db_info->ref_count);
+               refcount_inc(&db_info->ref_count);
 }
 
 /*
@@ -431,7 +431,7 @@ debug_info_put(debug_info_t *db_info)
 
        if (!db_info)
                return;
-       if (atomic_dec_and_test(&db_info->ref_count)) {
+       if (refcount_dec_and_test(&db_info->ref_count)) {
                for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
                        if (!db_info->views[i])
                                continue;
index a5f5d3bb3dbc516d23c98082d0f3abe186fc95c1..e408d9cc5b96adf40b873d8aabb3235793cd1b16 100644 (file)
@@ -312,6 +312,7 @@ ENTRY(system_call)
        lg      %r14,__LC_VDSO_PER_CPU
        lmg     %r0,%r10,__PT_R0(%r11)
        mvc     __LC_RETURN_PSW(16),__PT_PSW(%r11)
+.Lsysc_exit_timer:
        stpt    __LC_EXIT_TIMER
        mvc     __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
        lmg     %r11,%r15,__PT_R11(%r11)
@@ -623,6 +624,7 @@ ENTRY(io_int_handler)
        lg      %r14,__LC_VDSO_PER_CPU
        lmg     %r0,%r10,__PT_R0(%r11)
        mvc     __LC_RETURN_PSW(16),__PT_PSW(%r11)
+.Lio_exit_timer:
        stpt    __LC_EXIT_TIMER
        mvc     __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
        lmg     %r11,%r15,__PT_R11(%r11)
@@ -1174,15 +1176,23 @@ cleanup_critical:
        br      %r14
 
 .Lcleanup_sysc_restore:
+       # check if stpt has been executed
        clg     %r9,BASED(.Lcleanup_sysc_restore_insn)
+       jh      0f
+       mvc     __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       cghi    %r11,__LC_SAVE_AREA_ASYNC
        je      0f
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
+0:     clg     %r9,BASED(.Lcleanup_sysc_restore_insn+8)
+       je      1f
        lg      %r9,24(%r11)            # get saved pointer to pt_regs
        mvc     __LC_RETURN_PSW(16),__PT_PSW(%r9)
        mvc     0(64,%r11),__PT_R8(%r9)
        lmg     %r0,%r7,__PT_R0(%r9)
-0:     lmg     %r8,%r9,__LC_RETURN_PSW
+1:     lmg     %r8,%r9,__LC_RETURN_PSW
        br      %r14
 .Lcleanup_sysc_restore_insn:
+       .quad   .Lsysc_exit_timer
        .quad   .Lsysc_done - 4
 
 .Lcleanup_io_tif:
@@ -1190,15 +1200,20 @@ cleanup_critical:
        br      %r14
 
 .Lcleanup_io_restore:
+       # check if stpt has been executed
        clg     %r9,BASED(.Lcleanup_io_restore_insn)
-       je      0f
+       jh      0f
+       mvc     __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
+0:     clg     %r9,BASED(.Lcleanup_io_restore_insn+8)
+       je      1f
        lg      %r9,24(%r11)            # get saved r11 pointer to pt_regs
        mvc     __LC_RETURN_PSW(16),__PT_PSW(%r9)
        mvc     0(64,%r11),__PT_R8(%r9)
        lmg     %r0,%r7,__PT_R0(%r9)
-0:     lmg     %r8,%r9,__LC_RETURN_PSW
+1:     lmg     %r8,%r9,__LC_RETURN_PSW
        br      %r14
 .Lcleanup_io_restore_insn:
+       .quad   .Lio_exit_timer
        .quad   .Lio_done - 4
 
 .Lcleanup_idle:
index 27477f34cc0a9844a7391eef1e40ab28e3b1dcf1..d03a6d12c4bdc4118c3c10e0c80e90822cac6a03 100644 (file)
@@ -173,6 +173,8 @@ int __init ftrace_dyn_arch_init(void)
        return 0;
 }
 
+#ifdef CONFIG_MODULES
+
 static int __init ftrace_plt_init(void)
 {
        unsigned int *ip;
@@ -191,6 +193,8 @@ static int __init ftrace_plt_init(void)
 }
 device_initcall(ftrace_plt_init);
 
+#endif /* CONFIG_MODULES */
+
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 /*
  * Hook the return address and push it in the stack of return addresses
index 72307f108c40387fd718e9ca1e07ee5cb6ef9cb8..6e2c42bd1c3badbc4837176aeb1e266d86890bcf 100644 (file)
@@ -31,8 +31,14 @@ SECTIONS
 {
        . = 0x00000000;
        .text : {
-       _text = .;              /* Text and read-only data */
+               /* Text and read-only data */
                HEAD_TEXT
+               /*
+                * E.g. perf doesn't like symbols starting at address zero,
+                * therefore skip the initial PSW and channel program located
+                * at address zero and let _text start at 0x200.
+                */
+       _text = 0x200;
                TEXT_TEXT
                SCHED_TEXT
                CPUIDLE_TEXT
index ae90e1ae3607052c6ac4403f815d33061fcaf604..1963ddbf4ab385898160ce1d75881201b9c848c8 100644 (file)
@@ -4,6 +4,7 @@
  *    Copyright IBM Corp. 2014
  */
 
+#include <linux/errno.h>
 #include <asm/kprobes.h>
 #include <asm/dis.h>
 
index 1e5bb2b86c423fefee7987ec45483077748e8ca8..b3bd3f23b8e851c7f67e46cb527e20603512e7f5 100644 (file)
@@ -337,8 +337,8 @@ long __strncpy_from_user(char *dst, const char __user *src, long size)
                return 0;
        done = 0;
        do {
-               offset = (size_t)src & ~PAGE_MASK;
-               len = min(size - done, PAGE_SIZE - offset);
+               offset = (size_t)src & (L1_CACHE_BYTES - 1);
+               len = min(size - done, L1_CACHE_BYTES - offset);
                if (copy_from_user(dst, src, len))
                        return -EFAULT;
                len_str = strnlen(dst, len);
index dcbf985ab243201250222a824fc1146320522e65..d1f837dc77a4d0c975f94e5bbd315b347001d01a 100644 (file)
@@ -24,9 +24,11 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
 static inline int prepare_hugepage_range(struct file *file,
                        unsigned long addr, unsigned long len)
 {
-       if (len & ~HPAGE_MASK)
+       struct hstate *h = hstate_file(file);
+
+       if (len & ~huge_page_mask(h))
                return -EINVAL;
-       if (addr & ~HPAGE_MASK)
+       if (addr & ~huge_page_mask(h))
                return -EINVAL;
        return 0;
 }
index ce6f56980aefd2902bfae849eb90a993295976eb..cf190728360bbfb43621d23a7fb3a22c443a7399 100644 (file)
@@ -91,9 +91,9 @@ extern unsigned long pfn_base;
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
  */
-extern unsigned long empty_zero_page;
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 
-#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 
 /*
  * In general all page table modifications should use the V8 atomic
index 478bf6bb4598b345dd7f590beee86f43893e7645..3fae200dd251f094bad756ef145ec39882470d8e 100644 (file)
@@ -16,7 +16,7 @@ extern char reboot_command[];
  */
 extern unsigned char boot_cpu_id;
 
-extern unsigned long empty_zero_page;
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 
 extern int serial_console;
 static inline int con_is_present(void)
index 6bcff698069bf1fa57c1d84df180c1cb67f18a65..cec54dc4ab817e7c9c54c2d9b0532f0fd49bc7d8 100644 (file)
@@ -130,17 +130,16 @@ unsigned long prepare_ftrace_return(unsigned long parent,
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return parent + 8UL;
 
-       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
-                                    frame_pointer, NULL) == -EBUSY)
-               return parent + 8UL;
-
        trace.func = self_addr;
+       trace.depth = current->curr_ret_stack + 1;
 
        /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
-               current->curr_ret_stack--;
+       if (!ftrace_graph_entry(&trace))
+               return parent + 8UL;
+
+       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+                                    frame_pointer, NULL) == -EBUSY)
                return parent + 8UL;
-       }
 
        return return_hooker;
 }
index c6afe98de4d9aba5ebad292031735988afd8180d..3bd0d513bddbde7f95275be6e3ae94bd26729c6f 100644 (file)
@@ -290,7 +290,7 @@ void __init mem_init(void)
 
 
        /* Saves us work later. */
-       memset((void *)&empty_zero_page, 0, PAGE_SIZE);
+       memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
        i = last_valid_pfn >> ((20 - PAGE_SHIFT) + 5);
        i += 1;
index 9c761fea0c982e6dfd6acb949d7c8f738a50fd67..695605eb1dfbd941b591564fef723bd030c3316f 100644 (file)
@@ -43,7 +43,7 @@
 #define KVM_PRIVATE_MEM_SLOTS 3
 #define KVM_MEM_SLOTS_NUM (KVM_USER_MEM_SLOTS + KVM_PRIVATE_MEM_SLOTS)
 
-#define KVM_HALT_POLL_NS_DEFAULT 400000
+#define KVM_HALT_POLL_NS_DEFAULT 200000
 
 #define KVM_IRQCHIP_NUM_PINS  KVM_IOAPIC_NUM_PINS
 
index 68766b276d9eea540ef6aad3f43d4b52e6b8bf54..a059aac9e9377d26555c0dee3898b75e54ece194 100644 (file)
@@ -319,10 +319,10 @@ do {                                                                      \
 #define __get_user_asm_u64(x, ptr, retval, errret)                     \
 ({                                                                     \
        __typeof__(ptr) __ptr = (ptr);                                  \
-       asm volatile(ASM_STAC "\n"                                      \
+       asm volatile("\n"                                       \
                     "1:        movl %2,%%eax\n"                        \
                     "2:        movl %3,%%edx\n"                        \
-                    "3: " ASM_CLAC "\n"                                \
+                    "3:\n"                             \
                     ".section .fixup,\"ax\"\n"                         \
                     "4:        mov %4,%0\n"                            \
                     "  xorl %%eax,%%eax\n"                             \
@@ -331,7 +331,7 @@ do {                                                                        \
                     ".previous\n"                                      \
                     _ASM_EXTABLE(1b, 4b)                               \
                     _ASM_EXTABLE(2b, 4b)                               \
-                    : "=r" (retval), "=A"(x)                           \
+                    : "=r" (retval), "=&A"(x)                          \
                     : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \
                       "i" (errret), "0" (retval));                     \
 })
@@ -703,14 +703,15 @@ extern struct movsl_mask {
 #define unsafe_put_user(x, ptr, err_label)                                     \
 do {                                                                           \
        int __pu_err;                                                           \
-       __put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);         \
+       __typeof__(*(ptr)) __pu_val = (x);                                      \
+       __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);    \
        if (unlikely(__pu_err)) goto err_label;                                 \
 } while (0)
 
 #define unsafe_get_user(x, ptr, err_label)                                     \
 do {                                                                           \
        int __gu_err;                                                           \
-       unsigned long __gu_val;                                                 \
+       __inttype(*(ptr)) __gu_val;                                             \
        __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);    \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                             \
        if (unlikely(__gu_err)) goto err_label;                                 \
index c2f8dde3255ca706f613ff662d313ef1f06aa97d..d5d44c452624c88e3abb5c75e68d00b55fee6019 100644 (file)
@@ -90,6 +90,7 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
  * Boot time FPU feature detection code:
  */
 unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
+EXPORT_SYMBOL_GPL(mxcsr_feature_mask);
 
 static void __init fpu__init_system_mxcsr(void)
 {
index c25cfaf584e7285c10d23ee8d9240f22b7c94628..0816ab2e8adcae2b45f83c95c51e8b95a245b07e 100644 (file)
@@ -4173,7 +4173,7 @@ static int check_dr_write(struct x86_emulate_ctxt *ctxt)
 
 static int check_svme(struct x86_emulate_ctxt *ctxt)
 {
-       u64 efer;
+       u64 efer = 0;
 
        ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
 
index 56241746abbd71cae280621ec4b84d13b48bc81f..b0454c7e4cffe6c99e9619892a82afcd5d7ab70e 100644 (file)
@@ -283,11 +283,13 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
        pt_element_t pte;
        pt_element_t __user *uninitialized_var(ptep_user);
        gfn_t table_gfn;
-       unsigned index, pt_access, pte_access, accessed_dirty, pte_pkey;
+       u64 pt_access, pte_access;
+       unsigned index, accessed_dirty, pte_pkey;
        unsigned nested_access;
        gpa_t pte_gpa;
        bool have_ad;
        int offset;
+       u64 walk_nx_mask = 0;
        const int write_fault = access & PFERR_WRITE_MASK;
        const int user_fault  = access & PFERR_USER_MASK;
        const int fetch_fault = access & PFERR_FETCH_MASK;
@@ -302,6 +304,7 @@ retry_walk:
        have_ad       = PT_HAVE_ACCESSED_DIRTY(mmu);
 
 #if PTTYPE == 64
+       walk_nx_mask = 1ULL << PT64_NX_SHIFT;
        if (walker->level == PT32E_ROOT_LEVEL) {
                pte = mmu->get_pdptr(vcpu, (addr >> 30) & 3);
                trace_kvm_mmu_paging_element(pte, walker->level);
@@ -313,8 +316,6 @@ retry_walk:
        walker->max_level = walker->level;
        ASSERT(!(is_long_mode(vcpu) && !is_pae(vcpu)));
 
-       accessed_dirty = have_ad ? PT_GUEST_ACCESSED_MASK : 0;
-
        /*
         * FIXME: on Intel processors, loads of the PDPTE registers for PAE paging
         * by the MOV to CR instruction are treated as reads and do not cause the
@@ -322,14 +323,14 @@ retry_walk:
         */
        nested_access = (have_ad ? PFERR_WRITE_MASK : 0) | PFERR_USER_MASK;
 
-       pt_access = pte_access = ACC_ALL;
+       pte_access = ~0;
        ++walker->level;
 
        do {
                gfn_t real_gfn;
                unsigned long host_addr;
 
-               pt_access &= pte_access;
+               pt_access = pte_access;
                --walker->level;
 
                index = PT_INDEX(addr, walker->level);
@@ -371,6 +372,12 @@ retry_walk:
 
                trace_kvm_mmu_paging_element(pte, walker->level);
 
+               /*
+                * Inverting the NX it lets us AND it like other
+                * permission bits.
+                */
+               pte_access = pt_access & (pte ^ walk_nx_mask);
+
                if (unlikely(!FNAME(is_present_gpte)(pte)))
                        goto error;
 
@@ -379,14 +386,16 @@ retry_walk:
                        goto error;
                }
 
-               accessed_dirty &= pte;
-               pte_access = pt_access & FNAME(gpte_access)(vcpu, pte);
-
                walker->ptes[walker->level - 1] = pte;
        } while (!is_last_gpte(mmu, walker->level, pte));
 
        pte_pkey = FNAME(gpte_pkeys)(vcpu, pte);
-       errcode = permission_fault(vcpu, mmu, pte_access, pte_pkey, access);
+       accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0;
+
+       /* Convert to ACC_*_MASK flags for struct guest_walker.  */
+       walker->pt_access = FNAME(gpte_access)(vcpu, pt_access ^ walk_nx_mask);
+       walker->pte_access = FNAME(gpte_access)(vcpu, pte_access ^ walk_nx_mask);
+       errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access);
        if (unlikely(errcode))
                goto error;
 
@@ -403,7 +412,7 @@ retry_walk:
        walker->gfn = real_gpa >> PAGE_SHIFT;
 
        if (!write_fault)
-               FNAME(protect_clean_gpte)(mmu, &pte_access, pte);
+               FNAME(protect_clean_gpte)(mmu, &walker->pte_access, pte);
        else
                /*
                 * On a write fault, fold the dirty bit into accessed_dirty.
@@ -421,10 +430,8 @@ retry_walk:
                        goto retry_walk;
        }
 
-       walker->pt_access = pt_access;
-       walker->pte_access = pte_access;
        pgprintk("%s: pte %llx pte_access %x pt_access %x\n",
-                __func__, (u64)pte, pte_access, pt_access);
+                __func__, (u64)pte, walker->pte_access, walker->pt_access);
        return 1;
 
 error:
@@ -452,7 +459,7 @@ error:
         */
        if (!(errcode & PFERR_RSVD_MASK)) {
                vcpu->arch.exit_qualification &= 0x187;
-               vcpu->arch.exit_qualification |= ((pt_access & pte) & 0x7) << 3;
+               vcpu->arch.exit_qualification |= (pte_access & 0x7) << 3;
        }
 #endif
        walker->fault.address = addr;
index 9d4a8504a95a3ba687a5bd34b8ef3c58d4a5f2db..5ab4a364348e3c10987c33203be4ff6fa97e1e73 100644 (file)
@@ -294,7 +294,7 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
                        ((u64)1 << edx.split.bit_width_fixed) - 1;
        }
 
-       pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
+       pmu->global_ctrl = ((1ull << pmu->nr_arch_gp_counters) - 1) |
                (((1ull << pmu->nr_arch_fixed_counters) - 1) << INTEL_PMC_IDX_FIXED);
        pmu->global_ctrl_mask = ~pmu->global_ctrl;
 
index c27ac6923a18463751d153626f54413f9615201e..183ddb235fb48658028433d451db75d554152c54 100644 (file)
@@ -1272,7 +1272,8 @@ static void init_vmcb(struct vcpu_svm *svm)
 
 }
 
-static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu, int index)
+static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
+                                      unsigned int index)
 {
        u64 *avic_physical_id_table;
        struct kvm_arch *vm_data = &vcpu->kvm->arch;
index c6f4ad44aa95cc8f1a9013ad4fc54d22d5b2a5f7..72f78396bc0960968161b66ccee00c42fa203fb7 100644 (file)
@@ -6504,7 +6504,7 @@ static __init int hardware_setup(void)
                enable_ept_ad_bits = 0;
        }
 
-       if (!cpu_has_vmx_ept_ad_bits())
+       if (!cpu_has_vmx_ept_ad_bits() || !enable_ept)
                enable_ept_ad_bits = 0;
 
        if (!cpu_has_vmx_unrestricted_guest())
@@ -11213,7 +11213,7 @@ static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu)
                if (!nested_cpu_has_pml(vmcs12))
                        return 0;
 
-               if (vmcs12->guest_pml_index > PML_ENTITY_NUM) {
+               if (vmcs12->guest_pml_index >= PML_ENTITY_NUM) {
                        vmx->nested.pml_full = true;
                        return 1;
                }
index 464da936c53dd96b2f9e89f1f0ef715bac3eafe2..02363e37d4a61e8271d7fed0a8c534e9dd90f264 100644 (file)
@@ -1763,6 +1763,7 @@ u64 get_kvmclock_ns(struct kvm *kvm)
 {
        struct kvm_arch *ka = &kvm->arch;
        struct pvclock_vcpu_time_info hv_clock;
+       u64 ret;
 
        spin_lock(&ka->pvclock_gtod_sync_lock);
        if (!ka->use_master_clock) {
@@ -1774,10 +1775,17 @@ u64 get_kvmclock_ns(struct kvm *kvm)
        hv_clock.system_time = ka->master_kernel_ns + ka->kvmclock_offset;
        spin_unlock(&ka->pvclock_gtod_sync_lock);
 
+       /* both __this_cpu_read() and rdtsc() should be on the same cpu */
+       get_cpu();
+
        kvm_get_time_scale(NSEC_PER_SEC, __this_cpu_read(cpu_tsc_khz) * 1000LL,
                           &hv_clock.tsc_shift,
                           &hv_clock.tsc_to_system_mul);
-       return __pvclock_read_cycles(&hv_clock, rdtsc());
+       ret = __pvclock_read_cycles(&hv_clock, rdtsc());
+
+       put_cpu();
+
+       return ret;
 }
 
 static void kvm_setup_pvclock_page(struct kvm_vcpu *v)
@@ -3288,11 +3296,14 @@ static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
        }
 }
 
+#define XSAVE_MXCSR_OFFSET 24
+
 static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
                                        struct kvm_xsave *guest_xsave)
 {
        u64 xstate_bv =
                *(u64 *)&guest_xsave->region[XSAVE_HDR_OFFSET / sizeof(u32)];
+       u32 mxcsr = *(u32 *)&guest_xsave->region[XSAVE_MXCSR_OFFSET / sizeof(u32)];
 
        if (boot_cpu_has(X86_FEATURE_XSAVE)) {
                /*
@@ -3300,11 +3311,13 @@ static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
                 * CPUID leaf 0xD, index 0, EDX:EAX.  This is for compatibility
                 * with old userspace.
                 */
-               if (xstate_bv & ~kvm_supported_xcr0())
+               if (xstate_bv & ~kvm_supported_xcr0() ||
+                       mxcsr & ~mxcsr_feature_mask)
                        return -EINVAL;
                load_xsave(vcpu, (u8 *)guest_xsave->region);
        } else {
-               if (xstate_bv & ~XFEATURE_MASK_FPSSE)
+               if (xstate_bv & ~XFEATURE_MASK_FPSSE ||
+                       mxcsr & ~mxcsr_feature_mask)
                        return -EINVAL;
                memcpy(&vcpu->arch.guest_fpu.state.fxsave,
                        guest_xsave->region, sizeof(struct fxregs_state));
@@ -4818,16 +4831,20 @@ emul_write:
 
 static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
 {
-       /* TODO: String I/O for in kernel device */
-       int r;
+       int r = 0, i;
 
-       if (vcpu->arch.pio.in)
-               r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
-                                   vcpu->arch.pio.size, pd);
-       else
-               r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
-                                    vcpu->arch.pio.port, vcpu->arch.pio.size,
-                                    pd);
+       for (i = 0; i < vcpu->arch.pio.count; i++) {
+               if (vcpu->arch.pio.in)
+                       r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
+                                           vcpu->arch.pio.size, pd);
+               else
+                       r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
+                                            vcpu->arch.pio.port, vcpu->arch.pio.size,
+                                            pd);
+               if (r)
+                       break;
+               pd += vcpu->arch.pio.size;
+       }
        return r;
 }
 
@@ -4865,6 +4882,8 @@ static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
        if (vcpu->arch.pio.count)
                goto data_avail;
 
+       memset(vcpu->arch.pio_data, 0, size * count);
+
        ret = emulator_pio_in_out(vcpu, size, port, val, count, true);
        if (ret) {
 data_avail:
@@ -5048,6 +5067,8 @@ static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
 
        if (var.unusable) {
                memset(desc, 0, sizeof(*desc));
+               if (base3)
+                       *base3 = 0;
                return false;
        }
 
index 7cd442690f9dd6dc7af94d35f883becea31768bb..f33eef4ebd12b55645365732135638855ef313cd 100644 (file)
@@ -142,9 +142,7 @@ static void __init xen_banner(void)
        struct xen_extraversion extra;
        HYPERVISOR_xen_version(XENVER_extraversion, &extra);
 
-       pr_info("Booting paravirtualized kernel %son %s\n",
-               xen_feature(XENFEAT_auto_translated_physmap) ?
-                       "with PVH extensions " : "", pv_info.name);
+       pr_info("Booting paravirtualized kernel on %s\n", pv_info.name);
        printk(KERN_INFO "Xen version: %d.%d%s%s\n",
               version >> 16, version & 0xffff, extra.extraversion,
               xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
@@ -957,15 +955,10 @@ static void xen_write_msr(unsigned int msr, unsigned low, unsigned high)
 
 void xen_setup_shared_info(void)
 {
-       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               set_fixmap(FIX_PARAVIRT_BOOTMAP,
-                          xen_start_info->shared_info);
+       set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_start_info->shared_info);
 
-               HYPERVISOR_shared_info =
-                       (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
-       } else
-               HYPERVISOR_shared_info =
-                       (struct shared_info *)__va(xen_start_info->shared_info);
+       HYPERVISOR_shared_info =
+               (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
 
 #ifndef CONFIG_SMP
        /* In UP this is as good a place as any to set up shared info */
index 5e375a5e815fb2b90535429373c129c6aaa8862b..3be06f3caf3c1e25aa318fb2fd0ae8706cc0a717 100644 (file)
@@ -42,7 +42,7 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr)
 }
 EXPORT_SYMBOL_GPL(arbitrary_virt_to_machine);
 
-void xen_flush_tlb_all(void)
+static void xen_flush_tlb_all(void)
 {
        struct mmuext_op *op;
        struct multicall_space mcs;
index 7397d8b8459d65213967066a5eed7dc1d7b6cdfb..1f386d7fdf708489bf09b40c04ed338281c3e3c2 100644 (file)
@@ -355,10 +355,8 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
                pteval_t flags = val & PTE_FLAGS_MASK;
                unsigned long mfn;
 
-               if (!xen_feature(XENFEAT_auto_translated_physmap))
-                       mfn = __pfn_to_mfn(pfn);
-               else
-                       mfn = pfn;
+               mfn = __pfn_to_mfn(pfn);
+
                /*
                 * If there's no mfn for the pfn, then just create an
                 * empty non-present pte.  Unfortunately this loses
@@ -647,9 +645,6 @@ static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
        limit--;
        BUG_ON(limit >= FIXADDR_TOP);
 
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return 0;
-
        /*
         * 64-bit has a great big hole in the middle of the address
         * space, which contains the Xen mappings.  On 32-bit these
@@ -1289,9 +1284,6 @@ static void __init xen_pagetable_cleanhighmap(void)
 
 static void __init xen_pagetable_p2m_setup(void)
 {
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
        xen_vmalloc_p2m_tree();
 
 #ifdef CONFIG_X86_64
@@ -1314,8 +1306,7 @@ static void __init xen_pagetable_init(void)
        xen_build_mfn_list_list();
 
        /* Remap memory freed due to conflicts with E820 map */
-       if (!xen_feature(XENFEAT_auto_translated_physmap))
-               xen_remap_memory();
+       xen_remap_memory();
 
        xen_setup_shared_info();
 }
@@ -1925,21 +1916,20 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        /* Zap identity mapping */
        init_level4_pgt[0] = __pgd(0);
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               /* Pre-constructed entries are in pfn, so convert to mfn */
-               /* L4[272] -> level3_ident_pgt
-                * L4[511] -> level3_kernel_pgt */
-               convert_pfn_mfn(init_level4_pgt);
+       /* Pre-constructed entries are in pfn, so convert to mfn */
+       /* L4[272] -> level3_ident_pgt  */
+       /* L4[511] -> level3_kernel_pgt */
+       convert_pfn_mfn(init_level4_pgt);
 
-               /* L3_i[0] -> level2_ident_pgt */
-               convert_pfn_mfn(level3_ident_pgt);
-               /* L3_k[510] -> level2_kernel_pgt
-                * L3_k[511] -> level2_fixmap_pgt */
-               convert_pfn_mfn(level3_kernel_pgt);
+       /* L3_i[0] -> level2_ident_pgt */
+       convert_pfn_mfn(level3_ident_pgt);
+       /* L3_k[510] -> level2_kernel_pgt */
+       /* L3_k[511] -> level2_fixmap_pgt */
+       convert_pfn_mfn(level3_kernel_pgt);
+
+       /* L3_k[511][506] -> level1_fixmap_pgt */
+       convert_pfn_mfn(level2_fixmap_pgt);
 
-               /* L3_k[511][506] -> level1_fixmap_pgt */
-               convert_pfn_mfn(level2_fixmap_pgt);
-       }
        /* We get [511][511] and have Xen's version of level2_kernel_pgt */
        l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
        l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
@@ -1962,34 +1952,30 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
        if (i && i < pgd_index(__START_KERNEL_map))
                init_level4_pgt[i] = ((pgd_t *)xen_start_info->pt_base)[i];
 
-       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
-               /* Make pagetable pieces RO */
-               set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
-               set_page_prot(level2_ident_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
-               set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
-
-               /* Pin down new L4 */
-               pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
-                                 PFN_DOWN(__pa_symbol(init_level4_pgt)));
-
-               /* Unpin Xen-provided one */
-               pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+       /* Make pagetable pieces RO */
+       set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
+       set_page_prot(level2_ident_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
+       set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
+
+       /* Pin down new L4 */
+       pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
+                         PFN_DOWN(__pa_symbol(init_level4_pgt)));
+
+       /* Unpin Xen-provided one */
+       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
 
-               /*
-                * At this stage there can be no user pgd, and no page
-                * structure to attach it to, so make sure we just set kernel
-                * pgd.
-                */
-               xen_mc_batch();
-               __xen_write_cr3(true, __pa(init_level4_pgt));
-               xen_mc_issue(PARAVIRT_LAZY_CPU);
-       } else
-               native_write_cr3(__pa(init_level4_pgt));
+       /*
+        * At this stage there can be no user pgd, and no page structure to
+        * attach it to, so make sure we just set kernel pgd.
+        */
+       xen_mc_batch();
+       __xen_write_cr3(true, __pa(init_level4_pgt));
+       xen_mc_issue(PARAVIRT_LAZY_CPU);
 
        /* We can't that easily rip out L3 and L2, as the Xen pagetables are
         * set out this way: [L4], [L1], [L2], [L3], [L1], [L1] ...  for
@@ -2403,9 +2389,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
 
 static void __init xen_post_allocator_init(void)
 {
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
        pv_mmu_ops.set_pte = xen_set_pte;
        pv_mmu_ops.set_pmd = xen_set_pmd;
        pv_mmu_ops.set_pud = xen_set_pud;
@@ -2511,9 +2494,6 @@ void __init xen_init_mmu_ops(void)
 {
        x86_init.paging.pagetable_init = xen_pagetable_init;
 
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
        pv_mmu_ops = xen_mmu_ops;
 
        memset(dummy_mapping, 0xff, PAGE_SIZE);
@@ -2650,9 +2630,6 @@ int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
         * this function are redundant and can be ignored.
         */
 
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return 0;
-
        if (unlikely(order > MAX_CONTIG_ORDER))
                return -ENOMEM;
 
@@ -2689,9 +2666,6 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
        int success;
        unsigned long vstart;
 
-       if (xen_feature(XENFEAT_auto_translated_physmap))
-               return;
-
        if (unlikely(order > MAX_CONTIG_ORDER))
                return;
 
index 014af741fc6a3d78c769baa725774be7d9815851..4faa0fd53b0c120d39022ad726dbbe2c74f787bd 100644 (file)
@@ -764,6 +764,44 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
        return 0;
 }
 
+static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm,
+                                    const u8 *key, unsigned int keylen)
+{
+       unsigned long alignmask = crypto_skcipher_alignmask(tfm);
+       struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
+       u8 *buffer, *alignbuffer;
+       unsigned long absize;
+       int ret;
+
+       absize = keylen + alignmask;
+       buffer = kmalloc(absize, GFP_ATOMIC);
+       if (!buffer)
+               return -ENOMEM;
+
+       alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
+       memcpy(alignbuffer, key, keylen);
+       ret = cipher->setkey(tfm, alignbuffer, keylen);
+       kzfree(buffer);
+       return ret;
+}
+
+static int skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key,
+                          unsigned int keylen)
+{
+       struct skcipher_alg *cipher = crypto_skcipher_alg(tfm);
+       unsigned long alignmask = crypto_skcipher_alignmask(tfm);
+
+       if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
+               crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+               return -EINVAL;
+       }
+
+       if ((unsigned long)key & alignmask)
+               return skcipher_setkey_unaligned(tfm, key, keylen);
+
+       return cipher->setkey(tfm, key, keylen);
+}
+
 static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm)
 {
        struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
@@ -784,7 +822,7 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
            tfm->__crt_alg->cra_type == &crypto_givcipher_type)
                return crypto_init_skcipher_ops_ablkcipher(tfm);
 
-       skcipher->setkey = alg->setkey;
+       skcipher->setkey = skcipher_setkey;
        skcipher->encrypt = alg->encrypt;
        skcipher->decrypt = alg->decrypt;
        skcipher->ivsize = alg->ivsize;
index b7c2a06963d6fb79cb5f5aaa2576936d17d5088f..25aba9b107dd51db522225b5171e7017a5a3ec9d 100644 (file)
@@ -57,6 +57,7 @@
 
 #define ACPI_BUTTON_LID_INIT_IGNORE    0x00
 #define ACPI_BUTTON_LID_INIT_OPEN      0x01
+#define ACPI_BUTTON_LID_INIT_METHOD    0x02
 
 #define _COMPONENT             ACPI_BUTTON_COMPONENT
 ACPI_MODULE_NAME("button");
@@ -376,6 +377,9 @@ static void acpi_lid_initialize_state(struct acpi_device *device)
        case ACPI_BUTTON_LID_INIT_OPEN:
                (void)acpi_lid_notify_state(device, 1);
                break;
+       case ACPI_BUTTON_LID_INIT_METHOD:
+               (void)acpi_lid_update_state(device);
+               break;
        case ACPI_BUTTON_LID_INIT_IGNORE:
        default:
                break;
@@ -560,6 +564,9 @@ static int param_set_lid_init_state(const char *val, struct kernel_param *kp)
        if (!strncmp(val, "open", sizeof("open") - 1)) {
                lid_init_state = ACPI_BUTTON_LID_INIT_OPEN;
                pr_info("Notify initial lid state as open\n");
+       } else if (!strncmp(val, "method", sizeof("method") - 1)) {
+               lid_init_state = ACPI_BUTTON_LID_INIT_METHOD;
+               pr_info("Notify initial lid state with _LID return value\n");
        } else if (!strncmp(val, "ignore", sizeof("ignore") - 1)) {
                lid_init_state = ACPI_BUTTON_LID_INIT_IGNORE;
                pr_info("Do not notify initial lid state\n");
@@ -573,6 +580,8 @@ static int param_get_lid_init_state(char *buffer, struct kernel_param *kp)
        switch (lid_init_state) {
        case ACPI_BUTTON_LID_INIT_OPEN:
                return sprintf(buffer, "open");
+       case ACPI_BUTTON_LID_INIT_METHOD:
+               return sprintf(buffer, "method");
        case ACPI_BUTTON_LID_INIT_IGNORE:
                return sprintf(buffer, "ignore");
        default:
index f62082fdd6703e11c7576dc5db673dbc7dbba056..9c36b27996fc2b56a141bb388acf4947a45b104b 100644 (file)
@@ -512,13 +512,12 @@ static bool wakeup_source_not_registered(struct wakeup_source *ws)
 /**
  * wakup_source_activate - Mark given wakeup source as active.
  * @ws: Wakeup source to handle.
- * @hard: If set, abort suspends in progress and wake up from suspend-to-idle.
  *
  * Update the @ws' statistics and, if @ws has just been activated, notify the PM
  * core of the event by incrementing the counter of of wakeup events being
  * processed.
  */
-static void wakeup_source_activate(struct wakeup_source *ws, bool hard)
+static void wakeup_source_activate(struct wakeup_source *ws)
 {
        unsigned int cec;
 
@@ -526,9 +525,6 @@ static void wakeup_source_activate(struct wakeup_source *ws, bool hard)
                        "unregistered wakeup source\n"))
                return;
 
-       if (hard)
-               pm_system_wakeup();
-
        ws->active = true;
        ws->active_count++;
        ws->last_time = ktime_get();
@@ -554,7 +550,10 @@ static void wakeup_source_report_event(struct wakeup_source *ws, bool hard)
                ws->wakeup_count++;
 
        if (!ws->active)
-               wakeup_source_activate(ws, hard);
+               wakeup_source_activate(ws);
+
+       if (hard)
+               pm_system_wakeup();
 }
 
 /**
index b5730e17b45584ad4109df8c1c6eac5a35e81a4f..656624314f0d68dc7385b3896d0de9ae1a1cc457 100644 (file)
@@ -315,24 +315,32 @@ void drbd_req_complete(struct drbd_request *req, struct bio_and_error *m)
 }
 
 /* still holds resource->req_lock */
-static int drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
+static void drbd_req_put_completion_ref(struct drbd_request *req, struct bio_and_error *m, int put)
 {
        struct drbd_device *device = req->device;
        D_ASSERT(device, m || (req->rq_state & RQ_POSTPONED));
 
+       if (!put)
+               return;
+
        if (!atomic_sub_and_test(put, &req->completion_ref))
-               return 0;
+               return;
 
        drbd_req_complete(req, m);
 
+       /* local completion may still come in later,
+        * we need to keep the req object around. */
+       if (req->rq_state & RQ_LOCAL_ABORTED)
+               return;
+
        if (req->rq_state & RQ_POSTPONED) {
                /* don't destroy the req object just yet,
                 * but queue it for retry */
                drbd_restart_request(req);
-               return 0;
+               return;
        }
 
-       return 1;
+       kref_put(&req->kref, drbd_req_destroy);
 }
 
 static void set_if_null_req_next(struct drbd_peer_device *peer_device, struct drbd_request *req)
@@ -519,12 +527,8 @@ static void mod_rq_state(struct drbd_request *req, struct bio_and_error *m,
        if (req->i.waiting)
                wake_up(&device->misc_wait);
 
-       if (c_put) {
-               if (drbd_req_put_completion_ref(req, m, c_put))
-                       kref_put(&req->kref, drbd_req_destroy);
-       } else {
-               kref_put(&req->kref, drbd_req_destroy);
-       }
+       drbd_req_put_completion_ref(req, m, c_put);
+       kref_put(&req->kref, drbd_req_destroy);
 }
 
 static void drbd_report_io_error(struct drbd_device *device, struct drbd_request *req)
@@ -1366,8 +1370,7 @@ nodata:
        }
 
 out:
-       if (drbd_req_put_completion_ref(req, &m, 1))
-               kref_put(&req->kref, drbd_req_destroy);
+       drbd_req_put_completion_ref(req, &m, 1);
        spin_unlock_irq(&resource->req_lock);
 
        /* Even though above is a kref_put(), this is safe.
index 8fe61b5dc5a6553d141950506344fe90bbfde2c8..1f3dfaa54d871a36897408898c1e0e9f22100bb1 100644 (file)
@@ -504,11 +504,13 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
 
        dev_set_drvdata(&dev->dev, NULL);
 
-       if (be->blkif)
+       if (be->blkif) {
                xen_blkif_disconnect(be->blkif);
 
-       /* Put the reference we set in xen_blkif_alloc(). */
-       xen_blkif_put(be->blkif);
+               /* Put the reference we set in xen_blkif_alloc(). */
+               xen_blkif_put(be->blkif);
+       }
+
        kfree(be->mode);
        kfree(be);
        return 0;
index 565e4cf04a0215934e9b0f4df6f4398fbd0b2344..8249762192d55ed86a9794895a6faab01afe649e 100644 (file)
@@ -859,7 +859,11 @@ static int __init lp_setup (char *str)
        } else if (!strcmp(str, "auto")) {
                parport_nr[0] = LP_PARPORT_AUTO;
        } else if (!strcmp(str, "none")) {
-               parport_nr[parport_ptr++] = LP_PARPORT_NONE;
+               if (parport_ptr < LP_NO)
+                       parport_nr[parport_ptr++] = LP_PARPORT_NONE;
+               else
+                       printk(KERN_INFO "lp: too many ports, %s ignored.\n",
+                              str);
        } else if (!strcmp(str, "reset")) {
                reset = 1;
        }
index 7e4a9d1296bb7fb666f6b37ced2757a8585b7d75..6e0cbe09222059f0d8e8ccf821edfee5c575703e 100644 (file)
@@ -340,6 +340,11 @@ static const struct vm_operations_struct mmap_mem_ops = {
 static int mmap_mem(struct file *file, struct vm_area_struct *vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
+       phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT;
+
+       /* It's illegal to wrap around the end of the physical address space. */
+       if (offset + (phys_addr_t)size < offset)
+               return -EINVAL;
 
        if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
                return -EINVAL;
index 74ed7e9a7f27cd333a6bdf48144c0de4e6e7469e..2011fec2d6ad9d5b4ad1b089c38a1be23baeb509 100644 (file)
@@ -71,6 +71,15 @@ config ARM_HIGHBANK_CPUFREQ
 
          If in doubt, say N.
 
+config ARM_DB8500_CPUFREQ
+       tristate "ST-Ericsson DB8500 cpufreq" if COMPILE_TEST && !ARCH_U8500
+       default ARCH_U8500
+       depends on HAS_IOMEM
+       depends on !CPU_THERMAL || THERMAL
+       help
+         This adds the CPUFreq driver for ST-Ericsson Ux500 (DB8500) SoC
+         series.
+
 config ARM_IMX6Q_CPUFREQ
        tristate "Freescale i.MX6 cpufreq support"
        depends on ARCH_MXC
index b7e78f063c4f1d373bc892f84f68d6b8000a3051..ab3a42cd29ef210bcf0cad2ee48c74cb954b14f2 100644 (file)
@@ -53,7 +53,7 @@ obj-$(CONFIG_ARM_DT_BL_CPUFREQ)               += arm_big_little_dt.o
 
 obj-$(CONFIG_ARM_BRCMSTB_AVS_CPUFREQ)  += brcmstb-avs-cpufreq.o
 obj-$(CONFIG_ARCH_DAVINCI)             += davinci-cpufreq.o
-obj-$(CONFIG_UX500_SOC_DB8500)         += dbx500-cpufreq.o
+obj-$(CONFIG_ARM_DB8500_CPUFREQ)       += dbx500-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)   += exynos5440-cpufreq.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)     += highbank-cpufreq.o
 obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)                += imx6q-cpufreq.o
index ebf43f531adaff85da90968529ec522b2660776a..6ed32aac8bbeec9f139d0ba622d4b5fb6d1aca4b 100644 (file)
@@ -44,6 +44,7 @@ void dax_read_unlock(int id)
 }
 EXPORT_SYMBOL_GPL(dax_read_unlock);
 
+#ifdef CONFIG_BLOCK
 int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
                pgoff_t *pgoff)
 {
@@ -112,6 +113,7 @@ int __bdev_dax_supported(struct super_block *sb, int blocksize)
        return 0;
 }
 EXPORT_SYMBOL_GPL(__bdev_dax_supported);
+#endif
 
 /**
  * struct dax_device - anchor object for dax services
index 82dab1692264d04baeb409622d54bbd895e013ff..3aea5569816557b9b55503fb7fd654e9b088b6df 100644 (file)
@@ -782,24 +782,26 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
 
 static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
 {
-       u32 *dcsb = ctrl ? pvt->csels[1].csbases : pvt->csels[0].csbases;
-       int dimm, size0, size1;
+       int dimm, size0, size1, cs0, cs1;
 
        edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
 
        for (dimm = 0; dimm < 4; dimm++) {
                size0 = 0;
+               cs0 = dimm * 2;
 
-               if (dcsb[dimm*2] & DCSB_CS_ENABLE)
-                       size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm);
+               if (csrow_enabled(cs0, ctrl, pvt))
+                       size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
 
                size1 = 0;
-               if (dcsb[dimm*2 + 1] & DCSB_CS_ENABLE)
-                       size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, dimm);
+               cs1 = dimm * 2 + 1;
+
+               if (csrow_enabled(cs1, ctrl, pvt))
+                       size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
 
                amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
-                               dimm * 2,     size0,
-                               dimm * 2 + 1, size1);
+                               cs0,    size0,
+                               cs1,    size1);
        }
 }
 
@@ -2756,26 +2758,22 @@ skip:
  *     encompasses
  *
  */
-static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr)
+static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
 {
-       u32 cs_mode, nr_pages;
        u32 dbam = dct ? pvt->dbam1 : pvt->dbam0;
+       int csrow_nr = csrow_nr_orig;
+       u32 cs_mode, nr_pages;
 
+       if (!pvt->umc)
+               csrow_nr >>= 1;
 
-       /*
-        * The math on this doesn't look right on the surface because x/2*4 can
-        * be simplified to x*2 but this expression makes use of the fact that
-        * it is integral math where 1/2=0. This intermediate value becomes the
-        * number of bits to shift the DBAM register to extract the proper CSROW
-        * field.
-        */
-       cs_mode = DBAM_DIMM(csrow_nr / 2, dbam);
+       cs_mode = DBAM_DIMM(csrow_nr, dbam);
 
-       nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, (csrow_nr / 2))
-                                                          << (20 - PAGE_SHIFT);
+       nr_pages   = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
+       nr_pages <<= 20 - PAGE_SHIFT;
 
        edac_dbg(0, "csrow: %d, channel: %d, DBAM idx: %d\n",
-                   csrow_nr, dct,  cs_mode);
+                   csrow_nr_orig, dct,  cs_mode);
        edac_dbg(0, "nr_pages/channel: %u\n", nr_pages);
 
        return nr_pages;
index ed3137c1ceb0c0ed0fcbb1c94bffdf1a4811bf41..ef1fafdad4008ae7fa1824396592e0e53cf61002 100644 (file)
@@ -53,6 +53,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
        if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
                   &record->type, &part, &cnt, &time, &data_type) == 5) {
                record->id = generic_id(time, part, cnt);
+               record->part = part;
                record->count = cnt;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@ -64,6 +65,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
        } else if (sscanf(name, "dump-type%u-%u-%d-%lu",
                   &record->type, &part, &cnt, &time) == 4) {
                record->id = generic_id(time, part, cnt);
+               record->part = part;
                record->count = cnt;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@ -77,6 +79,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry,
                 * multiple logs, remains.
                 */
                record->id = generic_id(time, part, 0);
+               record->part = part;
                record->count = 0;
                record->time.tv_sec = time;
                record->time.tv_nsec = 0;
@@ -155,19 +158,14 @@ static int efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
  * efi_pstore_sysfs_entry_iter
  *
  * @record: pstore record to pass to callback
- * @pos: entry to begin iterating from
  *
  * You MUST call efivar_enter_iter_begin() before this function, and
  * efivar_entry_iter_end() afterwards.
  *
- * It is possible to begin iteration from an arbitrary entry within
- * the list by passing @pos. @pos is updated on return to point to
- * the next entry of the last one passed to efi_pstore_read_func().
- * To begin iterating from the beginning of the list @pos must be %NULL.
  */
-static int efi_pstore_sysfs_entry_iter(struct pstore_record *record,
-                                      struct efivar_entry **pos)
+static int efi_pstore_sysfs_entry_iter(struct pstore_record *record)
 {
+       struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data;
        struct efivar_entry *entry, *n;
        struct list_head *head = &efivar_sysfs_list;
        int size = 0;
@@ -218,7 +216,6 @@ static int efi_pstore_sysfs_entry_iter(struct pstore_record *record,
  */
 static ssize_t efi_pstore_read(struct pstore_record *record)
 {
-       struct efivar_entry *entry = (struct efivar_entry *)record->psi->data;
        ssize_t size;
 
        record->buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
@@ -229,7 +226,7 @@ static ssize_t efi_pstore_read(struct pstore_record *record)
                size = -EINTR;
                goto out;
        }
-       size = efi_pstore_sysfs_entry_iter(record, &entry);
+       size = efi_pstore_sysfs_entry_iter(record);
        efivar_entry_iter_end();
 
 out:
@@ -247,9 +244,15 @@ static int efi_pstore_write(struct pstore_record *record)
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        int i, ret = 0;
 
+       record->time.tv_sec = get_seconds();
+       record->time.tv_nsec = 0;
+
+       record->id = generic_id(record->time.tv_sec, record->part,
+                               record->count);
+
        snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu-%c",
                 record->type, record->part, record->count,
-                get_seconds(), record->compressed ? 'C' : 'D');
+                record->time.tv_sec, record->compressed ? 'C' : 'D');
 
        for (i = 0; i < DUMP_NAME_LEN; i++)
                efi_name[i] = name[i];
@@ -261,7 +264,6 @@ static int efi_pstore_write(struct pstore_record *record)
        if (record->reason == KMSG_DUMP_OOPS)
                efivar_run_worker();
 
-       record->id = record->part;
        return ret;
 };
 
@@ -293,7 +295,7 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
                 * holding multiple logs, remains.
                 */
                snprintf(name_old, sizeof(name_old), "dump-type%u-%u-%lu",
-                       ed->record->type, (unsigned int)ed->record->id,
+                       ed->record->type, ed->record->part,
                        ed->record->time.tv_sec);
 
                for (i = 0; i < DUMP_NAME_LEN; i++)
@@ -326,10 +328,7 @@ static int efi_pstore_erase(struct pstore_record *record)
        char name[DUMP_NAME_LEN];
        efi_char16_t efi_name[DUMP_NAME_LEN];
        int found, i;
-       unsigned int part;
 
-       do_div(record->id, 1000);
-       part = do_div(record->id, 100);
        snprintf(name, sizeof(name), "dump-type%u-%u-%d-%lu",
                 record->type, record->part, record->count,
                 record->time.tv_sec);
index 3ce813110d5e11bca8f3ea3e87c50cd32562b930..1e7860f02f4fa99e821e6a71bec7758621bc9a7d 100644 (file)
@@ -116,9 +116,13 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len,
                return VPD_OK;
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
-       info->key = kzalloc(key_len + 1, GFP_KERNEL);
-       if (!info->key)
+       if (!info)
                return -ENOMEM;
+       info->key = kzalloc(key_len + 1, GFP_KERNEL);
+       if (!info->key) {
+               ret = -ENOMEM;
+               goto free_info;
+       }
 
        memcpy(info->key, key, key_len);
 
@@ -135,12 +139,17 @@ static int vpd_section_attrib_add(const u8 *key, s32 key_len,
        list_add_tail(&info->list, &sec->attribs);
 
        ret = sysfs_create_bin_file(sec->kobj, &info->bin_attr);
-       if (ret) {
-               kfree(info->key);
-               return ret;
-       }
+       if (ret)
+               goto free_info_key;
 
        return 0;
+
+free_info_key:
+       kfree(info->key);
+free_info:
+       kfree(info);
+
+       return ret;
 }
 
 static void vpd_section_attrib_destroy(struct vpd_section *sec)
index 874ff32db36668919c50eb6eda3d744327ee5dd6..00cfed3c3e1a20b7bbea4b1a93e59fcd09afc2dd 100644 (file)
@@ -202,7 +202,8 @@ static int ti_sci_debugfs_create(struct platform_device *pdev,
        info->debug_buffer[info->debug_region_size] = 0;
 
        info->d = debugfs_create_file(strncat(debug_name, dev_name(dev),
-                                             sizeof(debug_name)),
+                                             sizeof(debug_name) -
+                                             sizeof("ti_sci_debug@")),
                                      0444, NULL, info, &ti_sci_debug_fops);
        if (IS_ERR(info->d))
                return PTR_ERR(info->d);
index 798a3cc480a2eefc8510417a883dcded6dedc741..1a3359c0f6cd2e80441977114ca55aea85c19cb8 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <drm/drmP.h>
+#include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
@@ -226,16 +227,33 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
                                    struct drm_plane_state *state)
 {
-       u32 src_w, src_h;
+       struct drm_rect clip = { 0 };
+       struct drm_crtc_state *crtc_state;
+       u32 src_h = state->src_h >> 16;
 
-       src_w = state->src_w >> 16;
-       src_h = state->src_h >> 16;
+       /* only the HDLCD_REG_FB_LINE_COUNT register has a limit */
+       if (src_h >= HDLCD_MAX_YRES) {
+               DRM_DEBUG_KMS("Invalid source width: %d\n", src_h);
+               return -EINVAL;
+       }
+
+       if (!state->fb || !state->crtc)
+               return 0;
 
-       /* we can't do any scaling of the plane source */
-       if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
+       crtc_state = drm_atomic_get_existing_crtc_state(state->state,
+                                                       state->crtc);
+       if (!crtc_state) {
+               DRM_DEBUG_KMS("Invalid crtc state\n");
                return -EINVAL;
+       }
 
-       return 0;
+       clip.x2 = crtc_state->adjusted_mode.hdisplay;
+       clip.y2 = crtc_state->adjusted_mode.vdisplay;
+
+       return drm_plane_helper_check_state(state, &clip,
+                                           DRM_PLANE_HELPER_NO_SCALING,
+                                           DRM_PLANE_HELPER_NO_SCALING,
+                                           false, true);
 }
 
 static void hdlcd_plane_atomic_update(struct drm_plane *plane,
@@ -244,21 +262,20 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
        struct drm_framebuffer *fb = plane->state->fb;
        struct hdlcd_drm_private *hdlcd;
        struct drm_gem_cma_object *gem;
-       u32 src_w, src_h, dest_w, dest_h;
+       u32 src_x, src_y, dest_h;
        dma_addr_t scanout_start;
 
        if (!fb)
                return;
 
-       src_w = plane->state->src_w >> 16;
-       src_h = plane->state->src_h >> 16;
-       dest_w = plane->state->crtc_w;
-       dest_h = plane->state->crtc_h;
+       src_x = plane->state->src.x1 >> 16;
+       src_y = plane->state->src.y1 >> 16;
+       dest_h = drm_rect_height(&plane->state->dst);
        gem = drm_fb_cma_get_gem_obj(fb, 0);
+
        scanout_start = gem->paddr + fb->offsets[0] +
-               plane->state->crtc_y * fb->pitches[0] +
-               plane->state->crtc_x *
-               fb->format->cpp[0];
+                       src_y * fb->pitches[0] +
+                       src_x * fb->format->cpp[0];
 
        hdlcd = plane->dev->dev_private;
        hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, fb->pitches[0]);
@@ -305,7 +322,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
                                       formats, ARRAY_SIZE(formats),
                                       DRM_PLANE_TYPE_PRIMARY, NULL);
        if (ret) {
-               devm_kfree(drm->dev, plane);
                return ERR_PTR(ret);
        }
 
@@ -329,7 +345,6 @@ int hdlcd_setup_crtc(struct drm_device *drm)
                                        &hdlcd_crtc_funcs, NULL);
        if (ret) {
                hdlcd_plane_destroy(primary);
-               devm_kfree(drm->dev, primary);
                return ret;
        }
 
index 65a3bd7a0c00dbf919d46e6d464d8bce8a5ccfd1..423dda2785d44fd2a900a406d7b1d86c3269d970 100644 (file)
@@ -152,8 +152,7 @@ static const struct drm_connector_funcs atmel_hlcdc_panel_connector_funcs = {
        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-static int atmel_hlcdc_attach_endpoint(struct drm_device *dev,
-                                      const struct device_node *np)
+static int atmel_hlcdc_attach_endpoint(struct drm_device *dev, int endpoint)
 {
        struct atmel_hlcdc_dc *dc = dev->dev_private;
        struct atmel_hlcdc_rgb_output *output;
@@ -161,6 +160,11 @@ static int atmel_hlcdc_attach_endpoint(struct drm_device *dev,
        struct drm_bridge *bridge;
        int ret;
 
+       ret = drm_of_find_panel_or_bridge(dev->dev->of_node, 0, endpoint,
+                                         &panel, &bridge);
+       if (ret)
+               return ret;
+
        output = devm_kzalloc(dev->dev, sizeof(*output), GFP_KERNEL);
        if (!output)
                return -EINVAL;
@@ -177,10 +181,6 @@ static int atmel_hlcdc_attach_endpoint(struct drm_device *dev,
 
        output->encoder.possible_crtcs = 0x1;
 
-       ret = drm_of_find_panel_or_bridge(np, 0, 0, &panel, &bridge);
-       if (ret)
-               return ret;
-
        if (panel) {
                output->connector.dpms = DRM_MODE_DPMS_OFF;
                output->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
@@ -220,22 +220,14 @@ err_encoder_cleanup:
 
 int atmel_hlcdc_create_outputs(struct drm_device *dev)
 {
-       struct device_node *remote;
-       int ret = -ENODEV;
-       int endpoint = 0;
-
-       while (true) {
-               /* Loop thru possible multiple connections to the output */
-               remote = of_graph_get_remote_node(dev->dev->of_node, 0,
-                                                 endpoint++);
-               if (!remote)
-                       break;
-
-               ret = atmel_hlcdc_attach_endpoint(dev, remote);
-               of_node_put(remote);
-               if (ret)
-                       return ret;
-       }
+       int endpoint, ret = 0;
+
+       for (endpoint = 0; !ret; endpoint++)
+               ret = atmel_hlcdc_attach_endpoint(dev, endpoint);
+
+       /* At least one device was successfully attached.*/
+       if (ret == -ENODEV && endpoint)
+               return 0;
 
        return ret;
 }
index e1909429837eebc2072d00d9a9f590c6e5f87bd2..de80ee1b71dfa2e8380b6e74b2d8cc6ed4aa6f25 100644 (file)
@@ -44,6 +44,7 @@ static struct etnaviv_gem_submit *submit_create(struct drm_device *dev,
 
                /* initially, until copy_from_user() and bo lookup succeeds: */
                submit->nr_bos = 0;
+               submit->fence = NULL;
 
                ww_acquire_init(&submit->ticket, &reservation_ww_class);
        }
@@ -294,7 +295,8 @@ static void submit_cleanup(struct etnaviv_gem_submit *submit)
        }
 
        ww_acquire_fini(&submit->ticket);
-       dma_fence_put(submit->fence);
+       if (submit->fence)
+               dma_fence_put(submit->fence);
        kfree(submit);
 }
 
index 0ad1a508e2af478dc9fb91df18bdc95304efad44..c995e540ff96e1f8a18a9232de2b26794fa03aa2 100644 (file)
@@ -1244,7 +1244,7 @@ static int dma_ctrl_write(struct intel_vgpu *vgpu, unsigned int offset,
        mode = vgpu_vreg(vgpu, offset);
 
        if (GFX_MODE_BIT_SET_IN_MASK(mode, START_DMA)) {
-               WARN_ONCE(1, "VM(%d): iGVT-g doesn't supporte GuC\n",
+               WARN_ONCE(1, "VM(%d): iGVT-g doesn't support GuC\n",
                                vgpu->id);
                return 0;
        }
index c6e7972ac21da8eda7143619a401554e2575a160..a5e11d89df2f86d13dc546f7b3e1a9e9c8ba7d97 100644 (file)
@@ -340,6 +340,9 @@ void intel_gvt_restore_render_mmio(struct intel_vgpu *vgpu, int ring_id)
                } else
                        v = mmio->value;
 
+               if (mmio->in_context)
+                       continue;
+
                I915_WRITE(mmio->reg, v);
                POSTING_READ(mmio->reg);
 
index 79ba4b3440aafd9537f287028d1e23a6186109a1..f25ff133865f1327936483ac166b97c41e0baa60 100644 (file)
@@ -129,9 +129,13 @@ static void try_to_schedule_next_vgpu(struct intel_gvt *gvt)
        struct vgpu_sched_data *vgpu_data;
        ktime_t cur_time;
 
-       /* no target to schedule */
-       if (!scheduler->next_vgpu)
+       /* no need to schedule if next_vgpu is the same with current_vgpu,
+        * let scheduler chose next_vgpu again by setting it to NULL.
+        */
+       if (scheduler->next_vgpu == scheduler->current_vgpu) {
+               scheduler->next_vgpu = NULL;
                return;
+       }
 
        /*
         * after the flag is set, workload dispatch thread will
index 2aa6b97fd22f28436b984a6ae9a537f36ada545a..a0563e18d753fd84731f8372efc7a938d2898a6b 100644 (file)
@@ -195,9 +195,12 @@ static int ppgtt_bind_vma(struct i915_vma *vma,
        u32 pte_flags;
        int ret;
 
-       ret = vma->vm->allocate_va_range(vma->vm, vma->node.start, vma->size);
-       if (ret)
-               return ret;
+       if (!(vma->flags & I915_VMA_LOCAL_BIND)) {
+               ret = vma->vm->allocate_va_range(vma->vm, vma->node.start,
+                                                vma->size);
+               if (ret)
+                       return ret;
+       }
 
        vma->pages = vma->obj->mm.pages;
 
@@ -2306,7 +2309,8 @@ static int aliasing_gtt_bind_vma(struct i915_vma *vma,
        if (flags & I915_VMA_LOCAL_BIND) {
                struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt;
 
-               if (appgtt->base.allocate_va_range) {
+               if (!(vma->flags & I915_VMA_LOCAL_BIND) &&
+                   appgtt->base.allocate_va_range) {
                        ret = appgtt->base.allocate_va_range(&appgtt->base,
                                                             vma->node.start,
                                                             vma->node.size);
index 11b12f4124920b07a65aaf7e02b81c8784bece46..5a7c63e64381e48a193610305973c468502565d2 100644 (file)
@@ -3051,10 +3051,14 @@ enum skl_disp_power_wells {
 #define CLKCFG_FSB_667                                 (3 << 0)        /* hrawclk 166 */
 #define CLKCFG_FSB_800                                 (2 << 0)        /* hrawclk 200 */
 #define CLKCFG_FSB_1067                                        (6 << 0)        /* hrawclk 266 */
+#define CLKCFG_FSB_1067_ALT                            (0 << 0)        /* hrawclk 266 */
 #define CLKCFG_FSB_1333                                        (7 << 0)        /* hrawclk 333 */
-/* Note, below two are guess */
-#define CLKCFG_FSB_1600                                        (4 << 0)        /* hrawclk 400 */
-#define CLKCFG_FSB_1600_ALT                            (0 << 0)        /* hrawclk 400 */
+/*
+ * Note that on at least on ELK the below value is reported for both
+ * 333 and 400 MHz BIOS FSB setting, but given that the gmch datasheet
+ * lists only 200/266/333 MHz FSB as supported let's decode it as 333 MHz.
+ */
+#define CLKCFG_FSB_1333_ALT                            (4 << 0)        /* hrawclk 333 */
 #define CLKCFG_FSB_MASK                                        (7 << 0)
 #define CLKCFG_MEM_533                                 (1 << 4)
 #define CLKCFG_MEM_667                                 (2 << 4)
index dd3ad52b7dfeac5e7d6f8eb59ee18b372f20a77f..f29a226e24d8836d86c6e976ce07bcfc26a53c28 100644 (file)
@@ -1798,13 +1798,11 @@ static int g4x_hrawclk(struct drm_i915_private *dev_priv)
        case CLKCFG_FSB_800:
                return 200000;
        case CLKCFG_FSB_1067:
+       case CLKCFG_FSB_1067_ALT:
                return 266667;
        case CLKCFG_FSB_1333:
+       case CLKCFG_FSB_1333_ALT:
                return 333333;
-       /* these two are just a guess; one of them might be right */
-       case CLKCFG_FSB_1600:
-       case CLKCFG_FSB_1600_ALT:
-               return 400000;
        default:
                return 133333;
        }
index 3ffe8b1f1d486f5e7352f50a62091cbb60831c83..fc0ef492252ac7c93f7b7ccb4e6a4b95d30f6294 100644 (file)
@@ -410,11 +410,10 @@ static void glk_dsi_device_ready(struct intel_encoder *encoder)
                val |= (ULPS_STATE_ENTER | DEVICE_READY);
                I915_WRITE(MIPI_DEVICE_READY(port), val);
 
-               /* Wait for ULPS Not active */
+               /* Wait for ULPS active */
                if (intel_wait_for_register(dev_priv,
-                               MIPI_CTRL(port), GLK_ULPS_NOT_ACTIVE,
-                               GLK_ULPS_NOT_ACTIVE, 20))
-                       DRM_ERROR("ULPS is still active\n");
+                               MIPI_CTRL(port), GLK_ULPS_NOT_ACTIVE, 0, 20))
+                       DRM_ERROR("ULPS not active\n");
 
                /* Exit ULPS */
                val = I915_READ(MIPI_DEVICE_READY(port));
index 25d8e76489e40ff989fd616386f03b36f9ba03fa..668f00480d97c0ff0418c19dfaaffec31fc65341 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/pci.h>
+#include <linux/pm_runtime.h>
 
 #include "i915_drv.h"
 #include <linux/delay.h>
@@ -121,6 +122,10 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
 
        kfree(rsc);
 
+       pm_runtime_forbid(&platdev->dev);
+       pm_runtime_set_active(&platdev->dev);
+       pm_runtime_enable(&platdev->dev);
+
        return platdev;
 
 err:
index 21b10f9840c95e29cd177e9e36d93b8d6155b48d..549763f5e17d8f3c2de2e5d6dbe460363e98c923 100644 (file)
@@ -360,6 +360,8 @@ nouveau_display_hpd_work(struct work_struct *work)
        pm_runtime_get_sync(drm->dev->dev);
 
        drm_helper_hpd_irq_event(drm->dev);
+       /* enable polling for external displays */
+       drm_kms_helper_poll_enable(drm->dev);
 
        pm_runtime_mark_last_busy(drm->dev->dev);
        pm_runtime_put_sync(drm->dev->dev);
@@ -413,10 +415,6 @@ nouveau_display_init(struct drm_device *dev)
        if (ret)
                return ret;
 
-       /* enable polling for external displays */
-       if (!dev->mode_config.poll_enabled)
-               drm_kms_helper_poll_enable(dev);
-
        /* enable hotplug interrupts */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                struct nouveau_connector *conn = nouveau_connector(connector);
index 2b6ac24ce6901013fd1dc99b4b4e8b27de6125db..36268e1802b5afcd65c6b3d623b273c4ac60af87 100644 (file)
@@ -502,6 +502,9 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
                pm_runtime_allow(dev->dev);
                pm_runtime_mark_last_busy(dev->dev);
                pm_runtime_put(dev->dev);
+       } else {
+               /* enable polling for external displays */
+               drm_kms_helper_poll_enable(dev);
        }
        return 0;
 
@@ -774,9 +777,6 @@ nouveau_pmops_runtime_resume(struct device *dev)
 
        ret = nouveau_do_resume(drm_dev, true);
 
-       if (!drm_dev->mode_config.poll_enabled)
-               drm_kms_helper_poll_enable(drm_dev);
-
        /* do magic */
        nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25));
        vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
index 3a24788c3185ba6a65156389b7a6b849d13d3a11..a7e55c422501cf9c4fc98bc7e7798d2b2213cfcf 100644 (file)
@@ -148,7 +148,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
        case NVKM_MEM_TARGET_NCOH: target = 3; break;
        default:
                WARN_ON(1);
-               return;
+               goto unlock;
        }
 
        nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
@@ -160,6 +160,7 @@ gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
                                       & 0x00100000),
                               msecs_to_jiffies(2000)) == 0)
                nvkm_error(subdev, "runlist %d update timeout\n", runl);
+unlock:
        mutex_unlock(&subdev->mutex);
 }
 
index d1cf02d22db1ff24926ddd881b7f15cbcd78d82c..1b0c793c0192b940103701142e5561ffb1b5263a 100644 (file)
@@ -116,6 +116,7 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
        ret = nvkm_firmware_get(subdev->device, f, &sig);
        if (ret)
                goto free_data;
+
        img->sig = kmemdup(sig->data, sig->size, GFP_KERNEL);
        if (!img->sig) {
                ret = -ENOMEM;
@@ -126,8 +127,9 @@ ls_ucode_img_load_gr(const struct nvkm_subdev *subdev, struct ls_ucode_img *img,
        img->ucode_data = ls_ucode_img_build(bl, code, data,
                                             &img->ucode_desc);
        if (IS_ERR(img->ucode_data)) {
+               kfree(img->sig);
                ret = PTR_ERR(img->ucode_data);
-               goto free_data;
+               goto free_sig;
        }
        img->ucode_size = img->ucode_desc.image_size;
 
index b2fd029d67b308ce60490d61cd908d743a9e520b..91916326957f9c3b842178b2c1cbdd60e9db5bf3 100644 (file)
@@ -1,6 +1,7 @@
 config TEGRA_HOST1X
        tristate "NVIDIA Tegra host1x driver"
        depends on ARCH_TEGRA || (ARM && COMPILE_TEST)
+       select IOMMU_IOVA if IOMMU_SUPPORT
        help
          Driver for the NVIDIA Tegra host1x hardware.
 
index 3ac4c03ba77ba3e0c79fd4dc11c606c09c8b3cbf..c13a4fd86b3cbaf47f48e1d7a24fa2c845513743 100644 (file)
@@ -604,6 +604,13 @@ static int coretemp_cpu_online(unsigned int cpu)
        struct cpuinfo_x86 *c = &cpu_data(cpu);
        struct platform_data *pdata;
 
+       /*
+        * Don't execute this on resume as the offline callback did
+        * not get executed on suspend.
+        */
+       if (cpuhp_tasks_frozen)
+               return 0;
+
        /*
         * CPUID.06H.EAX[0] indicates whether the CPU has thermal
         * sensors. We check this bit only, all the early CPUs
@@ -654,6 +661,13 @@ static int coretemp_cpu_offline(unsigned int cpu)
        struct temp_data *tdata;
        int indx, target;
 
+       /*
+        * Don't execute this on suspend as the device remove locks
+        * up the machine.
+        */
+       if (cpuhp_tasks_frozen)
+               return 0;
+
        /* If the physical CPU device does not exist, just return */
        if (!pdev)
                return 0;
index f2acd4b6bf0116fe2537c8d6b411b3279fd03959..d1263b82d646a1524697b38e2f63b31bd14f153d 100644 (file)
@@ -94,6 +94,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
        acpi_handle handle = ACPI_HANDLE(&pdev->dev);
        const struct acpi_device_id *id;
        struct acpi_device *adev;
@@ -107,23 +108,24 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
         * Try to get SDA hold time and *CNT values from an ACPI method for
         * selected speed modes.
         */
+       dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht);
+       dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht);
+       dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
+       dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
+
        switch (dev->clk_freq) {
        case 100000:
-               dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt,
-                                  &dev->sda_hold_time);
+               dev->sda_hold_time = ss_ht;
                break;
        case 1000000:
-               dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt,
-                                  &dev->sda_hold_time);
+               dev->sda_hold_time = fp_ht;
                break;
        case 3400000:
-               dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt,
-                                  &dev->sda_hold_time);
+               dev->sda_hold_time = hs_ht;
                break;
        case 400000:
        default:
-               dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
-                                  &dev->sda_hold_time);
+               dev->sda_hold_time = fs_ht;
                break;
        }
 
index cf737ec8563b873042a519e6f1337e3f095e10dd..5c4db65c5019b7692c645dfaec9d391623355a81 100644 (file)
@@ -819,7 +819,6 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
                rc = -EINVAL;
                goto out;
        }
-       drv_data->irq = irq_of_parse_and_map(np, 0);
 
        drv_data->rstc = devm_reset_control_get_optional(dev, NULL);
        if (IS_ERR(drv_data->rstc)) {
@@ -902,10 +901,11 @@ mv64xxx_i2c_probe(struct platform_device *pd)
        if (!IS_ERR(drv_data->clk))
                clk_prepare_enable(drv_data->clk);
 
+       drv_data->irq = platform_get_irq(pd, 0);
+
        if (pdata) {
                drv_data->freq_m = pdata->freq_m;
                drv_data->freq_n = pdata->freq_n;
-               drv_data->irq = platform_get_irq(pd, 0);
                drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
                drv_data->offload_enabled = false;
                memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
@@ -915,7 +915,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
                        goto exit_clk;
        }
        if (drv_data->irq < 0) {
-               rc = -ENXIO;
+               rc = drv_data->irq;
                goto exit_reset;
        }
 
index dbe7e44c9321279bbcd7b3f8d2006dbe1365e0b7..6ba6c83ca8f1bc9ee0c22bbb99e004e6bb50a77f 100644 (file)
@@ -416,6 +416,7 @@ static int xgene_slimpro_i2c_probe(struct platform_device *pdev)
        adapter->class = I2C_CLASS_HWMON;
        adapter->dev.parent = &pdev->dev;
        adapter->dev.of_node = pdev->dev.of_node;
+       ACPI_COMPANION_SET(&adapter->dev, ACPI_COMPANION(&pdev->dev));
        i2c_set_adapdata(adapter, ctx);
        rc = i2c_add_adapter(adapter);
        if (rc) {
index 26f7237558bad75f8a111037e725a37b519d751e..9669ca4937b891063d4cd63e552344d818f5eefa 100644 (file)
@@ -395,18 +395,20 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
        if (force_nr) {
                priv->adap.nr = force_nr;
                ret = i2c_add_numbered_adapter(&priv->adap);
-               dev_err(&parent->dev,
-                       "failed to add mux-adapter %u as bus %u (error=%d)\n",
-                       chan_id, force_nr, ret);
+               if (ret < 0) {
+                       dev_err(&parent->dev,
+                               "failed to add mux-adapter %u as bus %u (error=%d)\n",
+                               chan_id, force_nr, ret);
+                       goto err_free_priv;
+               }
        } else {
                ret = i2c_add_adapter(&priv->adap);
-               dev_err(&parent->dev,
-                       "failed to add mux-adapter %u (error=%d)\n",
-                       chan_id, ret);
-       }
-       if (ret < 0) {
-               kfree(priv);
-               return ret;
+               if (ret < 0) {
+                       dev_err(&parent->dev,
+                               "failed to add mux-adapter %u (error=%d)\n",
+                               chan_id, ret);
+                       goto err_free_priv;
+               }
        }
 
        WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
@@ -422,6 +424,10 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
 
        muxc->adapter[muxc->num_adapters++] = &priv->adap;
        return 0;
+
+err_free_priv:
+       kfree(priv);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(i2c_mux_add_adapter);
 
index 406d5059072cbe41964105d752a42236e66f7c8d..d97031804de8b477e9e77da0b2b31bb1abdcc907 100644 (file)
@@ -196,20 +196,25 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                mux->data.reg_size = resource_size(res);
                mux->data.reg = devm_ioremap_resource(&pdev->dev, res);
-               if (IS_ERR(mux->data.reg))
-                       return PTR_ERR(mux->data.reg);
+               if (IS_ERR(mux->data.reg)) {
+                       ret = PTR_ERR(mux->data.reg);
+                       goto err_put_parent;
+               }
        }
 
        if (mux->data.reg_size != 4 && mux->data.reg_size != 2 &&
            mux->data.reg_size != 1) {
                dev_err(&pdev->dev, "Invalid register size\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_put_parent;
        }
 
        muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0,
                             i2c_mux_reg_select, NULL);
-       if (!muxc)
-               return -ENOMEM;
+       if (!muxc) {
+               ret = -ENOMEM;
+               goto err_put_parent;
+       }
        muxc->priv = mux;
 
        platform_set_drvdata(pdev, muxc);
@@ -223,7 +228,7 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
 
                ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
                if (ret)
-                       goto add_adapter_failed;
+                       goto err_del_mux_adapters;
        }
 
        dev_dbg(&pdev->dev, "%d port mux on %s adapter\n",
@@ -231,8 +236,10 @@ static int i2c_mux_reg_probe(struct platform_device *pdev)
 
        return 0;
 
-add_adapter_failed:
+err_del_mux_adapters:
        i2c_mux_del_adapters(muxc);
+err_put_parent:
+       i2c_put_adapter(parent);
 
        return ret;
 }
index 8348f366ddd1a651817361cb9b8874ebdd3bc2bd..62618e77bedc9e2e8bf9ae241fcf127383735a73 100644 (file)
@@ -396,13 +396,13 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie,
                dma_addr_t iova, size_t size)
 {
        struct iova_domain *iovad = &cookie->iovad;
-       unsigned long shift = iova_shift(iovad);
 
        /* The MSI case is only ever cleaning up its most recent allocation */
        if (cookie->type == IOMMU_DMA_MSI_COOKIE)
                cookie->msi_iova -= size;
        else
-               free_iova_fast(iovad, iova >> shift, size >> shift);
+               free_iova_fast(iovad, iova_pfn(iovad, iova),
+                               size >> iova_shift(iovad));
 }
 
 static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr,
@@ -617,11 +617,14 @@ static dma_addr_t __iommu_dma_map(struct device *dev, phys_addr_t phys,
 {
        struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
        struct iommu_dma_cookie *cookie = domain->iova_cookie;
-       struct iova_domain *iovad = &cookie->iovad;
-       size_t iova_off = iova_offset(iovad, phys);
+       size_t iova_off = 0;
        dma_addr_t iova;
 
-       size = iova_align(iovad, size + iova_off);
+       if (cookie->type == IOMMU_DMA_IOVA_COOKIE) {
+               iova_off = iova_offset(&cookie->iovad, phys);
+               size = iova_align(&cookie->iovad, size + iova_off);
+       }
+
        iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev);
        if (!iova)
                return DMA_ERROR_CODE;
index 90ab0115d78e8dcc4512a6ab2efb27ac45a86c54..fc2765ccdb57496e257a0da0fd2177431a1c8713 100644 (file)
@@ -2055,11 +2055,14 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
        if (context_copied(context)) {
                u16 did_old = context_domain_id(context);
 
-               if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
+               if (did_old >= 0 && did_old < cap_ndoms(iommu->cap)) {
                        iommu->flush.flush_context(iommu, did_old,
                                                   (((u16)bus) << 8) | devfn,
                                                   DMA_CCMD_MASK_NOBIT,
                                                   DMA_CCMD_DEVICE_INVL);
+                       iommu->flush.flush_iotlb(iommu, did_old, 0, 0,
+                                                DMA_TLB_DSI_FLUSH);
+               }
        }
 
        pgd = domain->pgd;
index a27ef570c328d194d3528e81a64ea4f986e31ca6..bc1efbfb9ddf0f121a213f9919f7e3ea0fa957ca 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/device.h>
+#include <linux/dma-mapping.h>
 #include <linux/dma-iommu.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
index d2306c821ebb594398d102433dcc66efcb2bf573..31d6b5a582d28a2b4fdd0d0c0f0bf9e6113a9e4d 100644 (file)
@@ -106,10 +106,7 @@ static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
 static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
                                        u32 *mask, u32 *addr)
 {
-       unsigned int ofst;
-
-       hwirq -= RESERVED_IRQ_PER_MBIGEN_CHIP;
-       ofst = hwirq / 32 * 4;
+       unsigned int ofst = (hwirq / 32) * 4;
 
        *mask = 1 << (hwirq % 32);
        *addr = ofst + REG_MBIGEN_CLEAR_OFFSET;
@@ -337,9 +334,15 @@ static int mbigen_device_probe(struct platform_device *pdev)
        mgn_chip->pdev = pdev;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mgn_chip->base = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(mgn_chip->base))
-               return PTR_ERR(mgn_chip->base);
+       if (!res)
+               return -EINVAL;
+
+       mgn_chip->base = devm_ioremap(&pdev->dev, res->start,
+                                     resource_size(res));
+       if (!mgn_chip->base) {
+               dev_err(&pdev->dev, "failed to ioremap %pR\n", res);
+               return -ENOMEM;
+       }
 
        if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node)
                err = mbigen_of_create_domain(pdev, mgn_chip);
index 5db11a40512940df04d0dc871498830ec45f03ee..cd8139593ccd50655a2329460cc8de9d175eac86 100644 (file)
@@ -218,7 +218,7 @@ static DEFINE_SPINLOCK(param_spinlock);
  * Buffers are freed after this timeout
  */
 static unsigned dm_bufio_max_age = DM_BUFIO_DEFAULT_AGE_SECS;
-static unsigned dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
+static unsigned long dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
 
 static unsigned long dm_bufio_peak_allocated;
 static unsigned long dm_bufio_allocated_kmem_cache;
@@ -1558,10 +1558,10 @@ static bool __try_evict_buffer(struct dm_buffer *b, gfp_t gfp)
        return true;
 }
 
-static unsigned get_retain_buffers(struct dm_bufio_client *c)
+static unsigned long get_retain_buffers(struct dm_bufio_client *c)
 {
-        unsigned retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
-        return retain_bytes / c->block_size;
+        unsigned long retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
+        return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
 }
 
 static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
@@ -1571,7 +1571,7 @@ static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
        struct dm_buffer *b, *tmp;
        unsigned long freed = 0;
        unsigned long count = nr_to_scan;
-       unsigned retain_target = get_retain_buffers(c);
+       unsigned long retain_target = get_retain_buffers(c);
 
        for (l = 0; l < LIST_SIZE; l++) {
                list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) {
@@ -1794,8 +1794,8 @@ static bool older_than(struct dm_buffer *b, unsigned long age_hz)
 static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz)
 {
        struct dm_buffer *b, *tmp;
-       unsigned retain_target = get_retain_buffers(c);
-       unsigned count;
+       unsigned long retain_target = get_retain_buffers(c);
+       unsigned long count;
        LIST_HEAD(write_list);
 
        dm_bufio_lock(c);
@@ -1955,7 +1955,7 @@ MODULE_PARM_DESC(max_cache_size_bytes, "Size of metadata cache");
 module_param_named(max_age_seconds, dm_bufio_max_age, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(max_age_seconds, "Max age of a buffer in seconds");
 
-module_param_named(retain_bytes, dm_bufio_retain_bytes, uint, S_IRUGO | S_IWUSR);
+module_param_named(retain_bytes, dm_bufio_retain_bytes, ulong, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(retain_bytes, "Try to keep at least this many bytes cached in memory");
 
 module_param_named(peak_allocated_bytes, dm_bufio_peak_allocated, ulong, S_IRUGO | S_IWUSR);
index 9b1afdfb13f0f9510183ab916e642206023a60c5..70723389129163146666664e053d03e4263d677a 100644 (file)
@@ -33,6 +33,11 @@ struct background_tracker *btracker_create(unsigned max_work)
 {
        struct background_tracker *b = kmalloc(sizeof(*b), GFP_KERNEL);
 
+       if (!b) {
+               DMERR("couldn't create background_tracker");
+               return NULL;
+       }
+
        b->max_work = max_work;
        atomic_set(&b->pending_promotes, 0);
        atomic_set(&b->pending_writebacks, 0);
index 72479bd61e118e51c4bada036901ebe1bc4b1091..e5eb9c9b4bc8e8265c90debdc3d86eea98f08d96 100644 (file)
@@ -1120,8 +1120,6 @@ static bool clean_target_met(struct smq_policy *mq, bool idle)
         * Cache entries may not be populated.  So we cannot rely on the
         * size of the clean queue.
         */
-       unsigned nr_clean;
-
        if (idle) {
                /*
                 * We'd like to clean everything.
@@ -1129,18 +1127,16 @@ static bool clean_target_met(struct smq_policy *mq, bool idle)
                return q_size(&mq->dirty) == 0u;
        }
 
-       nr_clean = from_cblock(mq->cache_size) - q_size(&mq->dirty);
-       return (nr_clean + btracker_nr_writebacks_queued(mq->bg_work)) >=
-               percent_to_target(mq, CLEAN_TARGET);
+       /*
+        * If we're busy we don't worry about cleaning at all.
+        */
+       return true;
 }
 
-static bool free_target_met(struct smq_policy *mq, bool idle)
+static bool free_target_met(struct smq_policy *mq)
 {
        unsigned nr_free;
 
-       if (!idle)
-               return true;
-
        nr_free = from_cblock(mq->cache_size) - mq->cache_alloc.nr_allocated;
        return (nr_free + btracker_nr_demotions_queued(mq->bg_work)) >=
                percent_to_target(mq, FREE_TARGET);
@@ -1190,9 +1186,9 @@ static void queue_demotion(struct smq_policy *mq)
        if (unlikely(WARN_ON_ONCE(!mq->migrations_allowed)))
                return;
 
-       e = q_peek(&mq->clean, mq->clean.nr_levels, true);
+       e = q_peek(&mq->clean, mq->clean.nr_levels / 2, true);
        if (!e) {
-               if (!clean_target_met(mq, false))
+               if (!clean_target_met(mq, true))
                        queue_writeback(mq);
                return;
        }
@@ -1220,7 +1216,7 @@ static void queue_promotion(struct smq_policy *mq, dm_oblock_t oblock,
                 * We always claim to be 'idle' to ensure some demotions happen
                 * with continuous loads.
                 */
-               if (!free_target_met(mq, true))
+               if (!free_target_met(mq))
                        queue_demotion(mq);
                return;
        }
@@ -1421,14 +1417,10 @@ static int smq_get_background_work(struct dm_cache_policy *p, bool idle,
        spin_lock_irqsave(&mq->lock, flags);
        r = btracker_issue(mq->bg_work, result);
        if (r == -ENODATA) {
-               /* find some writeback work to do */
-               if (mq->migrations_allowed && !free_target_met(mq, idle))
-                       queue_demotion(mq);
-
-               else if (!clean_target_met(mq, idle))
+               if (!clean_target_met(mq, idle)) {
                        queue_writeback(mq);
-
-               r = btracker_issue(mq->bg_work, result);
+                       r = btracker_issue(mq->bg_work, result);
+               }
        }
        spin_unlock_irqrestore(&mq->lock, flags);
 
@@ -1452,6 +1444,7 @@ static void __complete_background_work(struct smq_policy *mq,
                clear_pending(mq, e);
                if (success) {
                        e->oblock = work->oblock;
+                       e->level = NR_CACHE_LEVELS - 1;
                        push(mq, e);
                        // h, q, a
                } else {
index 1db375f50a1321aae81492d1b3ac6392c52a00c2..d682a0511381aad0cadb7ab1f4eae9f815639aa1 100644 (file)
@@ -94,6 +94,9 @@ static void iot_io_begin(struct io_tracker *iot, sector_t len)
 
 static void __iot_io_end(struct io_tracker *iot, sector_t len)
 {
+       if (!len)
+               return;
+
        iot->in_flight -= len;
        if (!iot->in_flight)
                iot->idle_time = jiffies;
@@ -474,7 +477,7 @@ struct cache {
        spinlock_t invalidation_lock;
        struct list_head invalidation_requests;
 
-       struct io_tracker origin_tracker;
+       struct io_tracker tracker;
 
        struct work_struct commit_ws;
        struct batcher committer;
@@ -901,8 +904,7 @@ static dm_oblock_t get_bio_block(struct cache *cache, struct bio *bio)
 
 static bool accountable_bio(struct cache *cache, struct bio *bio)
 {
-       return ((bio->bi_bdev == cache->origin_dev->bdev) &&
-               bio_op(bio) != REQ_OP_DISCARD);
+       return bio_op(bio) != REQ_OP_DISCARD;
 }
 
 static void accounted_begin(struct cache *cache, struct bio *bio)
@@ -912,7 +914,7 @@ static void accounted_begin(struct cache *cache, struct bio *bio)
 
        if (accountable_bio(cache, bio)) {
                pb->len = bio_sectors(bio);
-               iot_io_begin(&cache->origin_tracker, pb->len);
+               iot_io_begin(&cache->tracker, pb->len);
        }
 }
 
@@ -921,7 +923,7 @@ static void accounted_complete(struct cache *cache, struct bio *bio)
        size_t pb_data_size = get_per_bio_data_size(cache);
        struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size);
 
-       iot_io_end(&cache->origin_tracker, pb->len);
+       iot_io_end(&cache->tracker, pb->len);
 }
 
 static void accounted_request(struct cache *cache, struct bio *bio)
@@ -1716,20 +1718,19 @@ static int invalidate_start(struct cache *cache, dm_cblock_t cblock,
 
 enum busy {
        IDLE,
-       MODERATE,
        BUSY
 };
 
 static enum busy spare_migration_bandwidth(struct cache *cache)
 {
-       bool idle = iot_idle_for(&cache->origin_tracker, HZ);
+       bool idle = iot_idle_for(&cache->tracker, HZ);
        sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
                cache->sectors_per_block;
 
-       if (current_volume <= cache->migration_threshold)
-               return idle ? IDLE : MODERATE;
+       if (idle && current_volume <= cache->migration_threshold)
+               return IDLE;
        else
-               return idle ? MODERATE : BUSY;
+               return BUSY;
 }
 
 static void inc_hit_counter(struct cache *cache, struct bio *bio)
@@ -2045,8 +2046,6 @@ static void check_migrations(struct work_struct *ws)
 
        for (;;) {
                b = spare_migration_bandwidth(cache);
-               if (b == BUSY)
-                       break;
 
                r = policy_get_background_work(cache->policy, b == IDLE, &op);
                if (r == -ENODATA)
@@ -2717,7 +2716,7 @@ static int cache_create(struct cache_args *ca, struct cache **result)
 
        batcher_init(&cache->committer, commit_op, cache,
                     issue_op, cache, cache->wq);
-       iot_init(&cache->origin_tracker);
+       iot_init(&cache->tracker);
 
        init_rwsem(&cache->background_work_lock);
        prevent_background_work(cache);
@@ -2941,7 +2940,7 @@ static void cache_postsuspend(struct dm_target *ti)
 
        cancel_delayed_work(&cache->waker);
        flush_workqueue(cache->wq);
-       WARN_ON(cache->origin_tracker.in_flight);
+       WARN_ON(cache->tracker.in_flight);
 
        /*
         * If it's a flush suspend there won't be any deferred bios, so this
index 926a6bcb32c8600118696119fd8ebe521cadbe5e..3df056b73b6610927a57058394a5bbe08f1b3404 100644 (file)
@@ -447,7 +447,7 @@ failed:
  * it has been invoked.
  */
 #define dm_report_EIO(m)                                               \
-({                                                                     \
+do {                                                                   \
        struct mapped_device *md = dm_table_get_md((m)->ti->table);     \
                                                                        \
        pr_debug("%s: returning EIO; QIFNP = %d; SQIFNP = %d; DNFS = %d\n", \
@@ -455,8 +455,7 @@ failed:
                 test_bit(MPATHF_QUEUE_IF_NO_PATH, &(m)->flags),        \
                 test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &(m)->flags),  \
                 dm_noflush_suspending((m)->ti));                       \
-       -EIO;                                                           \
-})
+} while (0)
 
 /*
  * Map cloned requests (request-based multipath)
@@ -481,7 +480,8 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
        if (!pgpath) {
                if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
                        return DM_MAPIO_DELAY_REQUEUE;
-               return dm_report_EIO(m);        /* Failed */
+               dm_report_EIO(m);       /* Failed */
+               return DM_MAPIO_KILL;
        } else if (test_bit(MPATHF_QUEUE_IO, &m->flags) ||
                   test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) {
                if (pg_init_all_paths(m))
@@ -558,7 +558,8 @@ static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_m
        if (!pgpath) {
                if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
                        return DM_MAPIO_REQUEUE;
-               return dm_report_EIO(m);
+               dm_report_EIO(m);
+               return -EIO;
        }
 
        mpio->pgpath = pgpath;
@@ -1493,7 +1494,7 @@ static int multipath_end_io(struct dm_target *ti, struct request *clone,
                if (atomic_read(&m->nr_valid_paths) == 0 &&
                    !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
                        if (error == -EIO)
-                               error = dm_report_EIO(m);
+                               dm_report_EIO(m);
                        /* complete with the original error */
                        r = DM_ENDIO_DONE;
                }
@@ -1524,8 +1525,10 @@ static int do_end_io_bio(struct multipath *m, struct bio *clone,
                fail_path(mpio->pgpath);
 
        if (atomic_read(&m->nr_valid_paths) == 0 &&
-           !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
-               return dm_report_EIO(m);
+           !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
+               dm_report_EIO(m);
+               return -EIO;
+       }
 
        /* Queue for the daemon to resubmit */
        dm_bio_restore(get_bio_details_from_bio(clone), clone);
index 2af27026aa2edd7ec0683c0d6f92ac3612eff0d4..b639fa7246eebec191aa8a084333391ab0435dfa 100644 (file)
@@ -507,6 +507,7 @@ static int map_request(struct dm_rq_target_io *tio)
        case DM_MAPIO_KILL:
                /* The target wants to complete the I/O */
                dm_kill_unmapped_request(rq, -EIO);
+               break;
        default:
                DMWARN("unimplemented target map return value: %d", r);
                BUG();
index 0f0251d0d337fff94b1e41d11940d658874eda17..d31d18d9727c69d555d7971e53ddde6b6c401bf3 100644 (file)
@@ -484,11 +484,11 @@ static int __write_initial_superblock(struct dm_pool_metadata *pmd)
        if (r < 0)
                return r;
 
-       r = save_sm_roots(pmd);
+       r = dm_tm_pre_commit(pmd->tm);
        if (r < 0)
                return r;
 
-       r = dm_tm_pre_commit(pmd->tm);
+       r = save_sm_roots(pmd);
        if (r < 0)
                return r;
 
index 82f798be964fc51d8c1d2d5b8cf5fc88392814ee..10367ffe92e3e37704f5e32793ea97175c8b15e6 100644 (file)
@@ -8022,18 +8022,15 @@ EXPORT_SYMBOL(md_write_end);
  * may proceed without blocking.  It is important to call this before
  * attempting a GFP_KERNEL allocation while holding the mddev lock.
  * Must be called with mddev_lock held.
- *
- * In the ->external case MD_SB_CHANGE_PENDING can not be cleared until mddev->lock
- * is dropped, so return -EAGAIN after notifying userspace.
  */
-int md_allow_write(struct mddev *mddev)
+void md_allow_write(struct mddev *mddev)
 {
        if (!mddev->pers)
-               return 0;
+               return;
        if (mddev->ro)
-               return 0;
+               return;
        if (!mddev->pers->sync_request)
-               return 0;
+               return;
 
        spin_lock(&mddev->lock);
        if (mddev->in_sync) {
@@ -8046,13 +8043,12 @@ int md_allow_write(struct mddev *mddev)
                spin_unlock(&mddev->lock);
                md_update_sb(mddev, 0);
                sysfs_notify_dirent_safe(mddev->sysfs_state);
+               /* wait for the dirty state to be recorded in the metadata */
+               wait_event(mddev->sb_wait,
+                          !test_bit(MD_SB_CHANGE_CLEAN, &mddev->sb_flags) &&
+                          !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
        } else
                spin_unlock(&mddev->lock);
-
-       if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags))
-               return -EAGAIN;
-       else
-               return 0;
 }
 EXPORT_SYMBOL_GPL(md_allow_write);
 
index 4e75d121bfcc5671640421769476c85d2843e7c9..11f15146ce5177de0468c706a5f82a037b42c132 100644 (file)
@@ -665,7 +665,7 @@ extern int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
                        bool metadata_op);
 extern void md_do_sync(struct md_thread *thread);
 extern void md_new_event(struct mddev *mddev);
-extern int md_allow_write(struct mddev *mddev);
+extern void md_allow_write(struct mddev *mddev);
 extern void md_wait_for_blocked_rdev(struct md_rdev *rdev, struct mddev *mddev);
 extern void md_set_array_sectors(struct mddev *mddev, sector_t array_sectors);
 extern int md_check_no_bitmap(struct mddev *mddev);
index ebb280a14325e1d937986926b40592c3b1847168..32adf6b4a9c7097e12796f8b396f80bfc8867c0a 100644 (file)
@@ -142,10 +142,23 @@ static int sm_disk_inc_block(struct dm_space_map *sm, dm_block_t b)
 
 static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
 {
+       int r;
+       uint32_t old_count;
        enum allocation_event ev;
        struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
 
-       return sm_ll_dec(&smd->ll, b, &ev);
+       r = sm_ll_dec(&smd->ll, b, &ev);
+       if (!r && (ev == SM_FREE)) {
+               /*
+                * It's only free if it's also free in the last
+                * transaction.
+                */
+               r = sm_ll_lookup(&smd->old_ll, b, &old_count);
+               if (!r && !old_count)
+                       smd->nr_allocated_this_transaction--;
+       }
+
+       return r;
 }
 
 static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
index 84e58596594db79f0dde1f789de9a200fb1f0e8c..d6c0bc76e837dff8636253f4daaea0aa16ce4d89 100644 (file)
@@ -385,7 +385,7 @@ static int raid0_run(struct mddev *mddev)
                blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
                blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors);
                blk_queue_max_write_zeroes_sectors(mddev->queue, mddev->chunk_sectors);
-               blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors);
+               blk_queue_max_discard_sectors(mddev->queue, UINT_MAX);
 
                blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
                blk_queue_io_opt(mddev->queue,
@@ -459,6 +459,95 @@ static inline int is_io_in_chunk_boundary(struct mddev *mddev,
        }
 }
 
+static void raid0_handle_discard(struct mddev *mddev, struct bio *bio)
+{
+       struct r0conf *conf = mddev->private;
+       struct strip_zone *zone;
+       sector_t start = bio->bi_iter.bi_sector;
+       sector_t end;
+       unsigned int stripe_size;
+       sector_t first_stripe_index, last_stripe_index;
+       sector_t start_disk_offset;
+       unsigned int start_disk_index;
+       sector_t end_disk_offset;
+       unsigned int end_disk_index;
+       unsigned int disk;
+
+       zone = find_zone(conf, &start);
+
+       if (bio_end_sector(bio) > zone->zone_end) {
+               struct bio *split = bio_split(bio,
+                       zone->zone_end - bio->bi_iter.bi_sector, GFP_NOIO,
+                       mddev->bio_set);
+               bio_chain(split, bio);
+               generic_make_request(bio);
+               bio = split;
+               end = zone->zone_end;
+       } else
+               end = bio_end_sector(bio);
+
+       if (zone != conf->strip_zone)
+               end = end - zone[-1].zone_end;
+
+       /* Now start and end is the offset in zone */
+       stripe_size = zone->nb_dev * mddev->chunk_sectors;
+
+       first_stripe_index = start;
+       sector_div(first_stripe_index, stripe_size);
+       last_stripe_index = end;
+       sector_div(last_stripe_index, stripe_size);
+
+       start_disk_index = (int)(start - first_stripe_index * stripe_size) /
+               mddev->chunk_sectors;
+       start_disk_offset = ((int)(start - first_stripe_index * stripe_size) %
+               mddev->chunk_sectors) +
+               first_stripe_index * mddev->chunk_sectors;
+       end_disk_index = (int)(end - last_stripe_index * stripe_size) /
+               mddev->chunk_sectors;
+       end_disk_offset = ((int)(end - last_stripe_index * stripe_size) %
+               mddev->chunk_sectors) +
+               last_stripe_index * mddev->chunk_sectors;
+
+       for (disk = 0; disk < zone->nb_dev; disk++) {
+               sector_t dev_start, dev_end;
+               struct bio *discard_bio = NULL;
+               struct md_rdev *rdev;
+
+               if (disk < start_disk_index)
+                       dev_start = (first_stripe_index + 1) *
+                               mddev->chunk_sectors;
+               else if (disk > start_disk_index)
+                       dev_start = first_stripe_index * mddev->chunk_sectors;
+               else
+                       dev_start = start_disk_offset;
+
+               if (disk < end_disk_index)
+                       dev_end = (last_stripe_index + 1) * mddev->chunk_sectors;
+               else if (disk > end_disk_index)
+                       dev_end = last_stripe_index * mddev->chunk_sectors;
+               else
+                       dev_end = end_disk_offset;
+
+               if (dev_end <= dev_start)
+                       continue;
+
+               rdev = conf->devlist[(zone - conf->strip_zone) *
+                       conf->strip_zone[0].nb_dev + disk];
+               if (__blkdev_issue_discard(rdev->bdev,
+                       dev_start + zone->dev_start + rdev->data_offset,
+                       dev_end - dev_start, GFP_NOIO, 0, &discard_bio) ||
+                   !discard_bio)
+                       continue;
+               bio_chain(discard_bio, bio);
+               if (mddev->gendisk)
+                       trace_block_bio_remap(bdev_get_queue(rdev->bdev),
+                               discard_bio, disk_devt(mddev->gendisk),
+                               bio->bi_iter.bi_sector);
+               generic_make_request(discard_bio);
+       }
+       bio_endio(bio);
+}
+
 static void raid0_make_request(struct mddev *mddev, struct bio *bio)
 {
        struct strip_zone *zone;
@@ -473,6 +562,11 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
                return;
        }
 
+       if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) {
+               raid0_handle_discard(mddev, bio);
+               return;
+       }
+
        bio_sector = bio->bi_iter.bi_sector;
        sector = bio_sector;
        chunk_sects = mddev->chunk_sectors;
@@ -498,19 +592,13 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
        bio->bi_iter.bi_sector = sector + zone->dev_start +
                tmp_dev->data_offset;
 
-       if (unlikely((bio_op(bio) == REQ_OP_DISCARD) &&
-                    !blk_queue_discard(bdev_get_queue(bio->bi_bdev)))) {
-               /* Just ignore it */
-               bio_endio(bio);
-       } else {
-               if (mddev->gendisk)
-                       trace_block_bio_remap(bdev_get_queue(bio->bi_bdev),
-                                             bio, disk_devt(mddev->gendisk),
-                                             bio_sector);
-               mddev_check_writesame(mddev, bio);
-               mddev_check_write_zeroes(mddev, bio);
-               generic_make_request(bio);
-       }
+       if (mddev->gendisk)
+               trace_block_bio_remap(bdev_get_queue(bio->bi_bdev),
+                                     bio, disk_devt(mddev->gendisk),
+                                     bio_sector);
+       mddev_check_writesame(mddev, bio);
+       mddev_check_write_zeroes(mddev, bio);
+       generic_make_request(bio);
 }
 
 static void raid0_status(struct seq_file *seq, struct mddev *mddev)
index 7ed59351fe972d60a8bf2bb22d20f4abaa718710..af5056d568788a53f6c3a2456a353cba3bbfe35a 100644 (file)
@@ -666,8 +666,11 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
                                        break;
                        }
                        continue;
-               } else
+               } else {
+                       if ((sectors > best_good_sectors) && (best_disk >= 0))
+                               best_disk = -1;
                        best_good_sectors = sectors;
+               }
 
                if (best_disk >= 0)
                        /* At least two disks to choose from so failfast is OK */
@@ -1529,17 +1532,16 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
                        plug = container_of(cb, struct raid1_plug_cb, cb);
                else
                        plug = NULL;
-               spin_lock_irqsave(&conf->device_lock, flags);
                if (plug) {
                        bio_list_add(&plug->pending, mbio);
                        plug->pending_cnt++;
                } else {
+                       spin_lock_irqsave(&conf->device_lock, flags);
                        bio_list_add(&conf->pending_bio_list, mbio);
                        conf->pending_count++;
-               }
-               spin_unlock_irqrestore(&conf->device_lock, flags);
-               if (!plug)
+                       spin_unlock_irqrestore(&conf->device_lock, flags);
                        md_wakeup_thread(mddev->thread);
+               }
        }
 
        r1_bio_write_done(r1_bio);
@@ -3197,7 +3199,7 @@ static int raid1_reshape(struct mddev *mddev)
        struct r1conf *conf = mddev->private;
        int cnt, raid_disks;
        unsigned long flags;
-       int d, d2, err;
+       int d, d2;
 
        /* Cannot change chunk_size, layout, or level */
        if (mddev->chunk_sectors != mddev->new_chunk_sectors ||
@@ -3209,11 +3211,8 @@ static int raid1_reshape(struct mddev *mddev)
                return -EINVAL;
        }
 
-       if (!mddev_is_clustered(mddev)) {
-               err = md_allow_write(mddev);
-               if (err)
-                       return err;
-       }
+       if (!mddev_is_clustered(mddev))
+               md_allow_write(mddev);
 
        raid_disks = mddev->raid_disks + mddev->delta_disks;
 
index 6b86a0032cf86683834c1ce82fcda6e6bd6b8e80..4343d7ff9916bee9a9a399572c2bd3313723fa3a 100644 (file)
@@ -1282,17 +1282,16 @@ static void raid10_write_one_disk(struct mddev *mddev, struct r10bio *r10_bio,
                plug = container_of(cb, struct raid10_plug_cb, cb);
        else
                plug = NULL;
-       spin_lock_irqsave(&conf->device_lock, flags);
        if (plug) {
                bio_list_add(&plug->pending, mbio);
                plug->pending_cnt++;
        } else {
+               spin_lock_irqsave(&conf->device_lock, flags);
                bio_list_add(&conf->pending_bio_list, mbio);
                conf->pending_count++;
-       }
-       spin_unlock_irqrestore(&conf->device_lock, flags);
-       if (!plug)
+               spin_unlock_irqrestore(&conf->device_lock, flags);
                md_wakeup_thread(mddev->thread);
+       }
 }
 
 static void raid10_write_request(struct mddev *mddev, struct bio *bio,
index 26ba09282e7c9691bdc352c5fb4b75b9f6e29821..4c00bc248287e4ab89b492225e0d054973725549 100644 (file)
@@ -24,6 +24,7 @@
 #include "md.h"
 #include "raid5.h"
 #include "bitmap.h"
+#include "raid5-log.h"
 
 /*
  * metadata/data stored in disk with 4k size unit (a block) regardless
@@ -622,20 +623,30 @@ static void r5l_do_submit_io(struct r5l_log *log, struct r5l_io_unit *io)
        __r5l_set_io_unit_state(io, IO_UNIT_IO_START);
        spin_unlock_irqrestore(&log->io_list_lock, flags);
 
+       /*
+        * In case of journal device failures, submit_bio will get error
+        * and calls endio, then active stripes will continue write
+        * process. Therefore, it is not necessary to check Faulty bit
+        * of journal device here.
+        *
+        * We can't check split_bio after current_bio is submitted. If
+        * io->split_bio is null, after current_bio is submitted, current_bio
+        * might already be completed and the io_unit is freed. We submit
+        * split_bio first to avoid the issue.
+        */
+       if (io->split_bio) {
+               if (io->has_flush)
+                       io->split_bio->bi_opf |= REQ_PREFLUSH;
+               if (io->has_fua)
+                       io->split_bio->bi_opf |= REQ_FUA;
+               submit_bio(io->split_bio);
+       }
+
        if (io->has_flush)
                io->current_bio->bi_opf |= REQ_PREFLUSH;
        if (io->has_fua)
                io->current_bio->bi_opf |= REQ_FUA;
        submit_bio(io->current_bio);
-
-       if (!io->split_bio)
-               return;
-
-       if (io->has_flush)
-               io->split_bio->bi_opf |= REQ_PREFLUSH;
-       if (io->has_fua)
-               io->split_bio->bi_opf |= REQ_FUA;
-       submit_bio(io->split_bio);
 }
 
 /* deferred io_unit will be dispatched here */
@@ -670,6 +681,11 @@ static void r5c_disable_writeback_async(struct work_struct *work)
                return;
        pr_info("md/raid:%s: Disabling writeback cache for degraded array.\n",
                mdname(mddev));
+
+       /* wait superblock change before suspend */
+       wait_event(mddev->sb_wait,
+                  !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
+
        mddev_suspend(mddev);
        log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH;
        mddev_resume(mddev);
@@ -2621,8 +2637,11 @@ int r5c_try_caching_write(struct r5conf *conf,
         * When run in degraded mode, array is set to write-through mode.
         * This check helps drain pending write safely in the transition to
         * write-through mode.
+        *
+        * When a stripe is syncing, the write is also handled in write
+        * through mode.
         */
-       if (s->failed) {
+       if (s->failed || test_bit(STRIPE_SYNCING, &sh->state)) {
                r5c_make_stripe_write_out(sh);
                return -EAGAIN;
        }
@@ -2825,6 +2844,9 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
        }
 
        r5l_append_flush_payload(log, sh->sector);
+       /* stripe is flused to raid disks, we can do resync now */
+       if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
+               set_bit(STRIPE_HANDLE, &sh->state);
 }
 
 int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)
@@ -2973,7 +2995,7 @@ ioerr:
        return ret;
 }
 
-void r5c_update_on_rdev_error(struct mddev *mddev)
+void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev)
 {
        struct r5conf *conf = mddev->private;
        struct r5l_log *log = conf->log;
@@ -2981,7 +3003,8 @@ void r5c_update_on_rdev_error(struct mddev *mddev)
        if (!log)
                return;
 
-       if (raid5_calc_degraded(conf) > 0 &&
+       if ((raid5_calc_degraded(conf) > 0 ||
+            test_bit(Journal, &rdev->flags)) &&
            conf->log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_BACK)
                schedule_work(&log->disable_writeback_work);
 }
index 27097101cccac90b739ce5564145114df2417f6b..328d67aedda49dcf2a7c93d1d188d77108794647 100644 (file)
@@ -28,7 +28,8 @@ extern void r5c_flush_cache(struct r5conf *conf, int num);
 extern void r5c_check_stripe_cache_usage(struct r5conf *conf);
 extern void r5c_check_cached_full_stripe(struct r5conf *conf);
 extern struct md_sysfs_entry r5c_journal_mode;
-extern void r5c_update_on_rdev_error(struct mddev *mddev);
+extern void r5c_update_on_rdev_error(struct mddev *mddev,
+                                    struct md_rdev *rdev);
 extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect);
 
 extern struct dma_async_tx_descriptor *
index 2e38cfac5b1dc5a318f66b4bb6e2e2195797ad53..9c4f7659f8b1337c99cfd0ab5070012e3f658849 100644 (file)
@@ -103,8 +103,7 @@ static inline void unlock_device_hash_lock(struct r5conf *conf, int hash)
 static inline void lock_all_device_hash_locks_irq(struct r5conf *conf)
 {
        int i;
-       local_irq_disable();
-       spin_lock(conf->hash_locks);
+       spin_lock_irq(conf->hash_locks);
        for (i = 1; i < NR_STRIPE_HASH_LOCKS; i++)
                spin_lock_nest_lock(conf->hash_locks + i, conf->hash_locks);
        spin_lock(&conf->device_lock);
@@ -114,9 +113,9 @@ static inline void unlock_all_device_hash_locks_irq(struct r5conf *conf)
 {
        int i;
        spin_unlock(&conf->device_lock);
-       for (i = NR_STRIPE_HASH_LOCKS; i; i--)
-               spin_unlock(conf->hash_locks + i - 1);
-       local_irq_enable();
+       for (i = NR_STRIPE_HASH_LOCKS - 1; i; i--)
+               spin_unlock(conf->hash_locks + i);
+       spin_unlock_irq(conf->hash_locks);
 }
 
 /* Find first data disk in a raid6 stripe */
@@ -234,11 +233,15 @@ static void do_release_stripe(struct r5conf *conf, struct stripe_head *sh,
                        if (test_bit(R5_InJournal, &sh->dev[i].flags))
                                injournal++;
        /*
-        * When quiesce in r5c write back, set STRIPE_HANDLE for stripes with
-        * data in journal, so they are not released to cached lists
+        * In the following cases, the stripe cannot be released to cached
+        * lists. Therefore, we make the stripe write out and set
+        * STRIPE_HANDLE:
+        *   1. when quiesce in r5c write back;
+        *   2. when resync is requested fot the stripe.
         */
-       if (conf->quiesce && r5c_is_writeback(conf->log) &&
-           !test_bit(STRIPE_HANDLE, &sh->state) && injournal != 0) {
+       if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) ||
+           (conf->quiesce && r5c_is_writeback(conf->log) &&
+            !test_bit(STRIPE_HANDLE, &sh->state) && injournal != 0)) {
                if (test_bit(STRIPE_R5C_CACHING, &sh->state))
                        r5c_make_stripe_write_out(sh);
                set_bit(STRIPE_HANDLE, &sh->state);
@@ -714,12 +717,11 @@ static bool is_full_stripe_write(struct stripe_head *sh)
 
 static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 {
-       local_irq_disable();
        if (sh1 > sh2) {
-               spin_lock(&sh2->stripe_lock);
+               spin_lock_irq(&sh2->stripe_lock);
                spin_lock_nested(&sh1->stripe_lock, 1);
        } else {
-               spin_lock(&sh1->stripe_lock);
+               spin_lock_irq(&sh1->stripe_lock);
                spin_lock_nested(&sh2->stripe_lock, 1);
        }
 }
@@ -727,8 +729,7 @@ static void lock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 static void unlock_two_stripes(struct stripe_head *sh1, struct stripe_head *sh2)
 {
        spin_unlock(&sh1->stripe_lock);
-       spin_unlock(&sh2->stripe_lock);
-       local_irq_enable();
+       spin_unlock_irq(&sh2->stripe_lock);
 }
 
 /* Only freshly new full stripe normal write stripe can be added to a batch list */
@@ -2312,14 +2313,12 @@ static int resize_stripes(struct r5conf *conf, int newsize)
        struct stripe_head *osh, *nsh;
        LIST_HEAD(newstripes);
        struct disk_info *ndisks;
-       int err;
+       int err = 0;
        struct kmem_cache *sc;
        int i;
        int hash, cnt;
 
-       err = md_allow_write(conf->mddev);
-       if (err)
-               return err;
+       md_allow_write(conf->mddev);
 
        /* Step 1 */
        sc = kmem_cache_create(conf->cache_name[1-conf->active_name],
@@ -2694,7 +2693,7 @@ static void raid5_error(struct mddev *mddev, struct md_rdev *rdev)
                bdevname(rdev->bdev, b),
                mdname(mddev),
                conf->raid_disks - mddev->degraded);
-       r5c_update_on_rdev_error(mddev);
+       r5c_update_on_rdev_error(mddev, rdev);
 }
 
 /*
@@ -3055,6 +3054,11 @@ sector_t raid5_compute_blocknr(struct stripe_head *sh, int i, int previous)
  *      When LOG_CRITICAL, stripes with injournal == 0 will be sent to
  *      no_space_stripes list.
  *
+ *   3. during journal failure
+ *      In journal failure, we try to flush all cached data to raid disks
+ *      based on data in stripe cache. The array is read-only to upper
+ *      layers, so we would skip all pending writes.
+ *
  */
 static inline bool delay_towrite(struct r5conf *conf,
                                 struct r5dev *dev,
@@ -3068,6 +3072,9 @@ static inline bool delay_towrite(struct r5conf *conf,
        if (test_bit(R5C_LOG_CRITICAL, &conf->cache_state) &&
            s->injournal > 0)
                return true;
+       /* case 3 above */
+       if (s->log_failed && s->injournal)
+               return true;
        return false;
 }
 
@@ -4653,8 +4660,13 @@ static void handle_stripe(struct stripe_head *sh)
 
        if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state) && !sh->batch_head) {
                spin_lock(&sh->stripe_lock);
-               /* Cannot process 'sync' concurrently with 'discard' */
-               if (!test_bit(STRIPE_DISCARD, &sh->state) &&
+               /*
+                * Cannot process 'sync' concurrently with 'discard'.
+                * Flush data in r5cache before 'sync'.
+                */
+               if (!test_bit(STRIPE_R5C_PARTIAL_STRIPE, &sh->state) &&
+                   !test_bit(STRIPE_R5C_FULL_STRIPE, &sh->state) &&
+                   !test_bit(STRIPE_DISCARD, &sh->state) &&
                    test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {
                        set_bit(STRIPE_SYNCING, &sh->state);
                        clear_bit(STRIPE_INSYNC, &sh->state);
@@ -4701,10 +4713,15 @@ static void handle_stripe(struct stripe_head *sh)
               " to_write=%d failed=%d failed_num=%d,%d\n",
               s.locked, s.uptodate, s.to_read, s.to_write, s.failed,
               s.failed_num[0], s.failed_num[1]);
-       /* check if the array has lost more than max_degraded devices and,
+       /*
+        * check if the array has lost more than max_degraded devices and,
         * if so, some requests might need to be failed.
+        *
+        * When journal device failed (log_failed), we will only process
+        * the stripe if there is data need write to raid disks
         */
-       if (s.failed > conf->max_degraded || s.log_failed) {
+       if (s.failed > conf->max_degraded ||
+           (s.log_failed && s.injournal == 0)) {
                sh->check_state = 0;
                sh->reconstruct_state = 0;
                break_stripe_batch_list(sh, 0);
@@ -5277,8 +5294,10 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf, int group)
        struct stripe_head *sh, *tmp;
        struct list_head *handle_list = NULL;
        struct r5worker_group *wg;
-       bool second_try = !r5c_is_writeback(conf->log);
-       bool try_loprio = test_bit(R5C_LOG_TIGHT, &conf->cache_state);
+       bool second_try = !r5c_is_writeback(conf->log) &&
+               !r5l_log_disk_error(conf);
+       bool try_loprio = test_bit(R5C_LOG_TIGHT, &conf->cache_state) ||
+               r5l_log_disk_error(conf);
 
 again:
        wg = NULL;
@@ -6313,7 +6332,6 @@ int
 raid5_set_cache_size(struct mddev *mddev, int size)
 {
        struct r5conf *conf = mddev->private;
-       int err;
 
        if (size <= 16 || size > 32768)
                return -EINVAL;
@@ -6325,10 +6343,7 @@ raid5_set_cache_size(struct mddev *mddev, int size)
                ;
        mutex_unlock(&conf->cache_size_mutex);
 
-
-       err = md_allow_write(mddev);
-       if (err)
-               return err;
+       md_allow_write(mddev);
 
        mutex_lock(&conf->cache_size_mutex);
        while (size > conf->max_nr_stripes)
@@ -7530,7 +7545,9 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
                 * neilb: there is no locking about new writes here,
                 * so this cannot be safe.
                 */
-               if (atomic_read(&conf->active_stripes)) {
+               if (atomic_read(&conf->active_stripes) ||
+                   atomic_read(&conf->r5c_cached_full_stripes) ||
+                   atomic_read(&conf->r5c_cached_partial_stripes)) {
                        return -EBUSY;
                }
                log_exit(conf);
index bf0fe0137dfed2c893001abb8cfe8b83861dae08..6d1b4b707cc287034c0d8fd225c4f7fc18e796ad 100644 (file)
@@ -512,7 +512,7 @@ static void gpmc_cs_show_timings(int cs, const char *desc)
        pr_info("gpmc cs%i access configuration:\n", cs);
        GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1,  4,  4, "time-para-granularity");
        GPMC_GET_RAW(GPMC_CS_CONFIG1,  8,  9, "mux-add-data");
-       GPMC_GET_RAW_MAX(GPMC_CS_CONFIG1, 12, 13,
+       GPMC_GET_RAW_SHIFT_MAX(GPMC_CS_CONFIG1, 12, 13, 1,
                         GPMC_CONFIG1_DEVICESIZE_MAX, "device-width");
        GPMC_GET_RAW(GPMC_CS_CONFIG1, 16, 17, "wait-pin");
        GPMC_GET_RAW_BOOL(GPMC_CS_CONFIG1, 21, 21, "wait-on-write");
index 2cba76e6fa3cb0bd8b2148bdd472c44f5abaf0d7..07bbd4cc18526514a2f1029b3d12b4d1b4724613 100644 (file)
@@ -492,6 +492,7 @@ config ASPEED_LPC_CTRL
 
 config PCI_ENDPOINT_TEST
        depends on PCI
+       select CRC32
        tristate "PCI Endpoint Test driver"
        ---help---
            Enable this configuration option to enable the host side test driver
index c5fd4259da331b27503644938ab22787e2eea8ae..b44a6aeb346d0404144dde0304a502268de1da91 100644 (file)
@@ -2577,7 +2577,7 @@ int __bond_3ad_get_active_agg_info(struct bonding *bond,
                return -1;
 
        ad_info->aggregator_id = aggregator->aggregator_identifier;
-       ad_info->ports = aggregator->num_of_ports;
+       ad_info->ports = __agg_active_ports(aggregator);
        ad_info->actor_key = aggregator->actor_oper_aggregator_key;
        ad_info->partner_key = aggregator->partner_oper_aggregator_key;
        ether_addr_copy(ad_info->partner_system,
index 2be78807fd6e1318487961708394caead76af268..73313318399c7b06b116b12e37b0b1b0277c4345 100644 (file)
@@ -4271,10 +4271,10 @@ static int bond_check_params(struct bond_params *params)
        int arp_validate_value, fail_over_mac_value, primary_reselect_value, i;
        struct bond_opt_value newval;
        const struct bond_opt_value *valptr;
-       int arp_all_targets_value;
+       int arp_all_targets_value = 0;
        u16 ad_actor_sys_prio = 0;
        u16 ad_user_port_key = 0;
-       __be32 arp_target[BOND_MAX_ARP_TARGETS];
+       __be32 arp_target[BOND_MAX_ARP_TARGETS] = { 0 };
        int arp_ip_count;
        int bond_mode   = BOND_MODE_ROUNDROBIN;
        int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
@@ -4501,7 +4501,6 @@ static int bond_check_params(struct bond_params *params)
                arp_validate_value = 0;
        }
 
-       arp_all_targets_value = 0;
        if (arp_all_targets) {
                bond_opt_initstr(&newval, arp_all_targets);
                valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_ALL_TARGETS),
index 19581d783d8ec7dc9ed9e5fd5a2891e8f2d22135..d034d8cd7d22dcde187f0becb24afd45480271f3 100644 (file)
@@ -849,6 +849,9 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
                mv88e6xxx_g1_stats_read(chip, reg, &low);
                if (s->sizeof_stat == 8)
                        mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
+               break;
+       default:
+               return UINT64_MAX;
        }
        value = (((u64)high) << 16) | low;
        return value;
index 4ee15ff06a448b72dbd6763427d9d02dfadad268..faeb4935ef3e3af5c998ef701e1e7cd2f5d739c8 100644 (file)
@@ -200,29 +200,18 @@ err_exit:
 static int hw_atl_a0_hw_offload_set(struct aq_hw_s *self,
                                    struct aq_nic_cfg_s *aq_nic_cfg)
 {
-       int err = 0;
-
        /* TX checksums offloads*/
        tpo_ipv4header_crc_offload_en_set(self, 1);
        tpo_tcp_udp_crc_offload_en_set(self, 1);
-       if (err < 0)
-               goto err_exit;
 
        /* RX checksums offloads*/
        rpo_ipv4header_crc_offload_en_set(self, 1);
        rpo_tcp_udp_crc_offload_en_set(self, 1);
-       if (err < 0)
-               goto err_exit;
 
        /* LSO offloads*/
        tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
-       if (err < 0)
-               goto err_exit;
-
-       err = aq_hw_err_from_flags(self);
 
-err_exit:
-       return err;
+       return aq_hw_err_from_flags(self);
 }
 
 static int hw_atl_a0_hw_init_tx_path(struct aq_hw_s *self)
index 42150708191dbf67d91b33218a2a275e9b5fd45d..1bceb7358e5ca3a4455badf55bc091d3705dc89d 100644 (file)
@@ -200,25 +200,18 @@ err_exit:
 static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
                                    struct aq_nic_cfg_s *aq_nic_cfg)
 {
-       int err = 0;
        unsigned int i;
 
        /* TX checksums offloads*/
        tpo_ipv4header_crc_offload_en_set(self, 1);
        tpo_tcp_udp_crc_offload_en_set(self, 1);
-       if (err < 0)
-               goto err_exit;
 
        /* RX checksums offloads*/
        rpo_ipv4header_crc_offload_en_set(self, 1);
        rpo_tcp_udp_crc_offload_en_set(self, 1);
-       if (err < 0)
-               goto err_exit;
 
        /* LSO offloads*/
        tdm_large_send_offload_en_set(self, 0xFFFFFFFFU);
-       if (err < 0)
-               goto err_exit;
 
 /* LRO offloads */
        {
@@ -245,10 +238,7 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self,
 
                rpo_lro_en_set(self, aq_nic_cfg->is_lro ? 0xFFFFFFFFU : 0U);
        }
-       err = aq_hw_err_from_flags(self);
-
-err_exit:
-       return err;
+       return aq_hw_err_from_flags(self);
 }
 
 static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self)
index 63f2deec2a52994684fa7a58763f68502265542e..77a1c03255defa77f2c662650d41a1ffc68eb7bb 100644 (file)
@@ -1353,6 +1353,7 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) &&
                pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
                printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n");
+               err = -EIO;
                goto err_dma;
        }
 
@@ -1366,10 +1367,11 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * pcibios_set_master to do the needed arch specific settings */
        pci_set_master(pdev);
 
-       err = -ENOMEM;
        netdev = alloc_etherdev(sizeof(struct atl2_adapter));
-       if (!netdev)
+       if (!netdev) {
+               err = -ENOMEM;
                goto err_alloc_etherdev;
+       }
 
        SET_NETDEV_DEV(netdev, &pdev->dev);
 
@@ -1408,8 +1410,6 @@ static int atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto err_sw_init;
 
-       err = -EIO;
-
        netdev->hw_features = NETIF_F_HW_VLAN_CTAG_RX;
        netdev->features |= (NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
 
index b56c54d68d5e3d6d8748a23b014ca4177c7d6dee..03f55daecb20b70bec8924eb64f2146a90591590 100644 (file)
@@ -7630,8 +7630,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->min_mtu = ETH_ZLEN;
        dev->max_mtu = BNXT_MAX_MTU;
 
-       bnxt_dcb_init(bp);
-
 #ifdef CONFIG_BNXT_SRIOV
        init_waitqueue_head(&bp->sriov_cfg_wait);
 #endif
@@ -7669,6 +7667,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        bnxt_hwrm_func_qcfg(bp);
        bnxt_hwrm_port_led_qcaps(bp);
        bnxt_ethtool_init(bp);
+       bnxt_dcb_init(bp);
 
        bnxt_set_rx_skb_mode(bp, false);
        bnxt_set_tpa_flags(bp);
index 46de2f8ff024aad59341ecf5963ccbd9082dae9e..5c6dd0ce209f627e4c5bd74efa1ef581d1eb46ad 100644 (file)
@@ -553,8 +553,10 @@ static u8 bnxt_dcbnl_setdcbx(struct net_device *dev, u8 mode)
        if ((mode & DCB_CAP_DCBX_VER_CEE) || !(mode & DCB_CAP_DCBX_VER_IEEE))
                return 1;
 
-       if ((mode & DCB_CAP_DCBX_HOST) && BNXT_VF(bp))
-               return 1;
+       if (mode & DCB_CAP_DCBX_HOST) {
+               if (BNXT_VF(bp) || (bp->flags & BNXT_FLAG_FW_LLDP_AGENT))
+                       return 1;
+       }
 
        if (mode == bp->dcbx_cap)
                return 0;
index fa376444e57c5668fc4c1ff027e56fdcc11bb55a..3549d387627888a2629b5f07dd1b001d2db1fc70 100644 (file)
@@ -37,7 +37,7 @@
 
 #define T4FW_VERSION_MAJOR 0x01
 #define T4FW_VERSION_MINOR 0x10
-#define T4FW_VERSION_MICRO 0x21
+#define T4FW_VERSION_MICRO 0x2B
 #define T4FW_VERSION_BUILD 0x00
 
 #define T4FW_MIN_VERSION_MAJOR 0x01
@@ -46,7 +46,7 @@
 
 #define T5FW_VERSION_MAJOR 0x01
 #define T5FW_VERSION_MINOR 0x10
-#define T5FW_VERSION_MICRO 0x21
+#define T5FW_VERSION_MICRO 0x2B
 #define T5FW_VERSION_BUILD 0x00
 
 #define T5FW_MIN_VERSION_MAJOR 0x00
@@ -55,7 +55,7 @@
 
 #define T6FW_VERSION_MAJOR 0x01
 #define T6FW_VERSION_MINOR 0x10
-#define T6FW_VERSION_MICRO 0x21
+#define T6FW_VERSION_MICRO 0x2B
 #define T6FW_VERSION_BUILD 0x00
 
 #define T6FW_MIN_VERSION_MAJOR 0x00
index 6ac336b546e6c226b1951c239a52b362052c04aa..1536356e2ea89ffaaf52974f1ed46b97ea861ae6 100644 (file)
@@ -1174,11 +1174,17 @@ static int ftmac100_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id ftmac100_of_ids[] = {
+       { .compatible = "andestech,atmac100" },
+       { }
+};
+
 static struct platform_driver ftmac100_driver = {
        .probe          = ftmac100_probe,
        .remove         = ftmac100_remove,
        .driver         = {
                .name   = DRV_NAME,
+               .of_match_table = ftmac100_of_ids
        },
 };
 
@@ -1202,3 +1208,4 @@ module_exit(ftmac100_exit);
 MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");
 MODULE_DESCRIPTION("FTMAC100 driver");
 MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, ftmac100_of_ids);
index 703205475524d689cd2762f2d2ce3abfd2b6ebcb..83aab1e4c8c8c76f73a598c5bdde51e185d9121a 100644 (file)
@@ -2862,12 +2862,10 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
        int port = 0;
 
        if (msi_x) {
-               int nreq = dev->caps.num_ports * num_online_cpus() + 1;
-
-               nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
-                            nreq);
-               if (nreq > MAX_MSIX)
-                       nreq = MAX_MSIX;
+               int nreq = min3(dev->caps.num_ports *
+                               (int)num_online_cpus() + 1,
+                               dev->caps.num_eqs - dev->caps.reserved_eqs,
+                               MAX_MSIX);
 
                entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
                if (!entries)
index fc52d742b7f7a52885bc78cfcb23acbd738bc552..27251a78075ccba1c4e151b54387aa987dc17210 100644 (file)
@@ -13,7 +13,7 @@ config MLX5_CORE
 
 config MLX5_CORE_EN
        bool "Mellanox Technologies ConnectX-4 Ethernet support"
-       depends on NETDEVICES && ETHERNET && PCI && MLX5_CORE
+       depends on NETDEVICES && ETHERNET && INET && PCI && MLX5_CORE
        depends on IPV6=y || IPV6=n || MLX5_CORE=m
        imply PTP_1588_CLOCK
        default n
index 0099a3e397bcf8758388b44e0e44888b35468920..2fd044b238750fedc61384fda55bf25206d25b51 100644 (file)
@@ -1003,7 +1003,7 @@ int mlx5e_create_direct_tirs(struct mlx5e_priv *priv);
 void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv);
 void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt);
 
-int mlx5e_create_ttc_table(struct mlx5e_priv *priv, u32 underlay_qpn);
+int mlx5e_create_ttc_table(struct mlx5e_priv *priv);
 void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv);
 
 int mlx5e_create_tis(struct mlx5_core_dev *mdev, int tc,
index ce7b09d72ff68b1850f6df3845f2fd9ae7f57bbd..8209affa75c3e5e0419634740d6985970f61fa67 100644 (file)
@@ -794,7 +794,6 @@ static void get_supported(u32 eth_proto_cap,
        ptys2ethtool_supported_port(link_ksettings, eth_proto_cap);
        ptys2ethtool_supported_link(supported, eth_proto_cap);
        ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
-       ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Asym_Pause);
 }
 
 static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
@@ -804,7 +803,7 @@ static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
        unsigned long *advertising = link_ksettings->link_modes.advertising;
 
        ptys2ethtool_adver_link(advertising, eth_proto_cap);
-       if (tx_pause)
+       if (rx_pause)
                ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
        if (tx_pause ^ rx_pause)
                ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
@@ -849,6 +848,8 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
        struct mlx5e_priv *priv    = netdev_priv(netdev);
        struct mlx5_core_dev *mdev = priv->mdev;
        u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {0};
+       u32 rx_pause = 0;
+       u32 tx_pause = 0;
        u32 eth_proto_cap;
        u32 eth_proto_admin;
        u32 eth_proto_lp;
@@ -871,11 +872,13 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
        an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
        an_status        = MLX5_GET(ptys_reg, out, an_status);
 
+       mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
+
        ethtool_link_ksettings_zero_link_mode(link_ksettings, supported);
        ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
 
        get_supported(eth_proto_cap, link_ksettings);
-       get_advertising(eth_proto_admin, 0, 0, link_ksettings);
+       get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings);
        get_speed_duplex(netdev, eth_proto_oper, link_ksettings);
 
        eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
index 576d6787b484b6387c55a172a65fa838b50e198a..53ed58320a24aef89e40230c67728ea01bd086ac 100644 (file)
@@ -800,7 +800,7 @@ void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
        mlx5e_destroy_flow_table(&ttc->ft);
 }
 
-int mlx5e_create_ttc_table(struct mlx5e_priv *priv, u32 underlay_qpn)
+int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
 {
        struct mlx5e_ttc_table *ttc = &priv->fs.ttc;
        struct mlx5_flow_table_attr ft_attr = {};
@@ -810,7 +810,6 @@ int mlx5e_create_ttc_table(struct mlx5e_priv *priv, u32 underlay_qpn)
        ft_attr.max_fte = MLX5E_TTC_TABLE_SIZE;
        ft_attr.level = MLX5E_TTC_FT_LEVEL;
        ft_attr.prio = MLX5E_NIC_PRIO;
-       ft_attr.underlay_qpn = underlay_qpn;
 
        ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
        if (IS_ERR(ft->t)) {
@@ -1147,7 +1146,7 @@ int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
                priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
        }
 
-       err = mlx5e_create_ttc_table(priv, 0);
+       err = mlx5e_create_ttc_table(priv);
        if (err) {
                netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
                           err);
index a61b71b6fff30358e43602b1f84e16c697e3140f..41cd22a223dccbd9dae460331525a1fc2414be9e 100644 (file)
@@ -2976,7 +2976,7 @@ static int mlx5e_setup_tc(struct net_device *netdev, u8 tc)
        new_channels.params = priv->channels.params;
        new_channels.params.num_tc = tc ? tc : 1;
 
-       if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
+       if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
                priv->channels.params = new_channels.params;
                goto out;
        }
index 19e3d2fc2099e09a987d0d475629580c72cd37c0..fcec7bedd3cd348f78ec25703d4e77a6e005f596 100644 (file)
 #include "eswitch.h"
 
 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
-                           struct mlx5_flow_table *ft)
+                           struct mlx5_flow_table *ft, u32 underlay_qpn)
 {
        u32 in[MLX5_ST_SZ_DW(set_flow_table_root_in)]   = {0};
        u32 out[MLX5_ST_SZ_DW(set_flow_table_root_out)] = {0};
 
        if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) &&
-           ft->underlay_qpn == 0)
+           underlay_qpn == 0)
                return 0;
 
        MLX5_SET(set_flow_table_root_in, in, opcode,
                 MLX5_CMD_OP_SET_FLOW_TABLE_ROOT);
        MLX5_SET(set_flow_table_root_in, in, table_type, ft->type);
        MLX5_SET(set_flow_table_root_in, in, table_id, ft->id);
+       MLX5_SET(set_flow_table_root_in, in, underlay_qpn, underlay_qpn);
        if (ft->vport) {
                MLX5_SET(set_flow_table_root_in, in, vport_number, ft->vport);
                MLX5_SET(set_flow_table_root_in, in, other_vport, 1);
        }
 
-       if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) &&
-           ft->underlay_qpn != 0)
-               MLX5_SET(set_flow_table_root_in, in, underlay_qpn, ft->underlay_qpn);
-
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
 
index 8fad806885362dce727791213422b7a9c0d5b897..0f98a7cf4877d8103ef03989e15d05eda570fdb2 100644 (file)
@@ -71,7 +71,8 @@ int mlx5_cmd_delete_fte(struct mlx5_core_dev *dev,
                        unsigned int index);
 
 int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
-                           struct mlx5_flow_table *ft);
+                           struct mlx5_flow_table *ft,
+                           u32 underlay_qpn);
 
 int mlx5_cmd_fc_alloc(struct mlx5_core_dev *dev, u16 *id);
 int mlx5_cmd_fc_free(struct mlx5_core_dev *dev, u16 id);
index b8a176503d384f863de75cacf7bd81d1f40ad9d8..0e487e8ca634bce0108979823e755918fe27c3fb 100644 (file)
@@ -650,7 +650,7 @@ static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
        if (ft->level >= min_level)
                return 0;
 
-       err = mlx5_cmd_update_root_ft(root->dev, ft);
+       err = mlx5_cmd_update_root_ft(root->dev, ft, root->underlay_qpn);
        if (err)
                mlx5_core_warn(root->dev, "Update root flow table of id=%u failed\n",
                               ft->id);
@@ -818,8 +818,6 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
                goto unlock_root;
        }
 
-       ft->underlay_qpn = ft_attr->underlay_qpn;
-
        tree_init_node(&ft->node, 1, del_flow_table);
        log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0;
        next_ft = find_next_chained_ft(fs_prio);
@@ -1489,7 +1487,8 @@ static int update_root_ft_destroy(struct mlx5_flow_table *ft)
 
        new_root_ft = find_next_ft(ft);
        if (new_root_ft) {
-               int err = mlx5_cmd_update_root_ft(root->dev, new_root_ft);
+               int err = mlx5_cmd_update_root_ft(root->dev, new_root_ft,
+                                                 root->underlay_qpn);
 
                if (err) {
                        mlx5_core_warn(root->dev, "Update root flow table of id=%u failed\n",
@@ -2062,3 +2061,21 @@ err:
        mlx5_cleanup_fs(dev);
        return err;
 }
+
+int mlx5_fs_add_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn)
+{
+       struct mlx5_flow_root_namespace *root = dev->priv.steering->root_ns;
+
+       root->underlay_qpn = underlay_qpn;
+       return 0;
+}
+EXPORT_SYMBOL(mlx5_fs_add_rx_underlay_qpn);
+
+int mlx5_fs_remove_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn)
+{
+       struct mlx5_flow_root_namespace *root = dev->priv.steering->root_ns;
+
+       root->underlay_qpn = 0;
+       return 0;
+}
+EXPORT_SYMBOL(mlx5_fs_remove_rx_underlay_qpn);
index 81eafc7b9dd93fc4c8411aa8ad473299ca6c623e..990acee6fb091f102e7412c499df8df44eb806db 100644 (file)
@@ -118,7 +118,6 @@ struct mlx5_flow_table {
        /* FWD rules that point on this flow table */
        struct list_head                fwd_rules;
        u32                             flags;
-       u32                             underlay_qpn;
 };
 
 struct mlx5_fc_cache {
@@ -195,6 +194,7 @@ struct mlx5_flow_root_namespace {
        struct mlx5_flow_table          *root_ft;
        /* Should be held when chaining flow tables */
        struct mutex                    chain_lock;
+       u32                             underlay_qpn;
 };
 
 int mlx5_init_fc_stats(struct mlx5_core_dev *dev);
index 019c230da498f4d540cfb253a5c5f06edffeee05..cc1858752e70818650ca86a00795b3bb48668fb6 100644 (file)
@@ -66,6 +66,10 @@ static void mlx5i_init(struct mlx5_core_dev *mdev,
 
        mlx5e_build_nic_params(mdev, &priv->channels.params, profile->max_nch(mdev));
 
+       /* Override RQ params as IPoIB supports only LINKED LIST RQ for now */
+       mlx5e_set_rq_type_params(mdev, &priv->channels.params, MLX5_WQ_TYPE_LINKED_LIST);
+       priv->channels.params.lro_en = false;
+
        mutex_init(&priv->state_lock);
 
        netdev->hw_features    |= NETIF_F_SG;
@@ -156,6 +160,8 @@ out:
 
 static void mlx5i_destroy_underlay_qp(struct mlx5_core_dev *mdev, struct mlx5_core_qp *qp)
 {
+       mlx5_fs_remove_rx_underlay_qpn(mdev, qp->qpn);
+
        mlx5_core_destroy_qp(mdev, qp);
 }
 
@@ -170,6 +176,8 @@ static int mlx5i_init_tx(struct mlx5e_priv *priv)
                return err;
        }
 
+       mlx5_fs_add_rx_underlay_qpn(priv->mdev, ipriv->qp.qpn);
+
        err = mlx5e_create_tis(priv->mdev, 0 /* tc */, ipriv->qp.qpn, &priv->tisn[0]);
        if (err) {
                mlx5_core_warn(priv->mdev, "create tis failed, %d\n", err);
@@ -189,7 +197,6 @@ static void mlx5i_cleanup_tx(struct mlx5e_priv *priv)
 
 static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
 {
-       struct mlx5i_priv *ipriv = priv->ppriv;
        int err;
 
        priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
@@ -205,7 +212,7 @@ static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
                priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
        }
 
-       err = mlx5e_create_ttc_table(priv, ipriv->qp.qpn);
+       err = mlx5e_create_ttc_table(priv);
        if (err) {
                netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
                           err);
index ea56f6ade6b429585f35a2f72dae20f8d51d4a0f..5f0a7bc692a4b8e3efae2f8a3c8a55f5c448346d 100644 (file)
@@ -199,10 +199,11 @@ static int mlxsw_sp_erif_entry_get(struct mlxsw_sp *mlxsw_sp,
 
        entry->counter_valid = false;
        entry->counter = 0;
+       entry->index = mlxsw_sp_rif_index(rif);
+
        if (!counters_enabled)
                return 0;
 
-       entry->index = mlxsw_sp_rif_index(rif);
        err = mlxsw_sp_rif_counter_value_get(mlxsw_sp, rif,
                                             MLXSW_SP_RIF_COUNTER_EGRESS,
                                             &cnt);
index 33cec1cc164259ad9d7dd022a811e957447a61ff..9f89c4137d2137f78bcda8f79a918b8db61a5189 100644 (file)
@@ -206,6 +206,9 @@ void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
 {
        unsigned int *p_counter_index;
 
+       if (!mlxsw_sp_rif_counter_valid_get(rif, dir))
+               return;
+
        p_counter_index = mlxsw_sp_rif_p_counter_get(rif, dir);
        if (WARN_ON(!p_counter_index))
                return;
index 0d8411f1f954c5668bc3bd26f721589f2ccf205d..f4bb0c0b7c1d2689a884d64010fde0f0dfd4053c 100644 (file)
@@ -1497,8 +1497,7 @@ do_fdb_op:
        err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid,
                                      adding, true);
        if (err) {
-               if (net_ratelimit())
-                       netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
+               dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n");
                return;
        }
 
@@ -1558,8 +1557,7 @@ do_fdb_op:
        err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
                                          adding, true);
        if (err) {
-               if (net_ratelimit())
-                       netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
+               dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n");
                return;
        }
 
index b8d5270359cd8a7109226c0be1731cbafa6d1423..e306765155290a31e390f5ddcf88b4f0aa8f973c 100644 (file)
@@ -247,7 +247,7 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
        cmd.req.arg3 = 0;
 
        if (recv_ctx->state == NX_HOST_CTX_STATE_ACTIVE)
-               netxen_issue_cmd(adapter, &cmd);
+               rcode = netxen_issue_cmd(adapter, &cmd);
 
        if (rcode != NX_RCODE_SUCCESS)
                return -EIO;
index 67200c5498ab01d3911735f25e6ccea05aed200e..0a8fde6299919b3c1e0d7382ac90be30631644e3 100644 (file)
@@ -983,7 +983,7 @@ void qed_set_rfs_mode_disable(struct qed_hwfn *p_hwfn,
        memset(&camline, 0, sizeof(union gft_cam_line_union));
        qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id,
               camline.cam_line_mapped.camline);
-       memset(&ramline, 0, sizeof(union gft_cam_line_union));
+       memset(&ramline, 0, sizeof(ramline));
 
        for (i = 0; i < RAM_LINE_SIZE / REG_SIZE; i++) {
                u32 hw_addr = PRS_REG_GFT_PROFILE_MASK_RAM;
index 49bad00a0f8f994837b0554f3250d5ca0811bff7..7245b1072518fff31566c471b6eb32b512e41846 100644 (file)
@@ -37,8 +37,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 3
-#define _QLCNIC_LINUX_SUBVERSION 65
-#define QLCNIC_LINUX_VERSIONID  "5.3.65"
+#define _QLCNIC_LINUX_SUBVERSION 66
+#define QLCNIC_LINUX_VERSIONID  "5.3.66"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
                 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
index 718bf58a7da66284e121f3aab8e79de7a6221c67..4fb68797630e9531e7ffc4e7bc7c015313a44063 100644 (file)
@@ -3168,6 +3168,40 @@ int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr,
        return 0;
 }
 
+void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter)
+{
+       struct qlcnic_hardware_context *ahw = adapter->ahw;
+       struct qlcnic_cmd_args cmd;
+       u32 config;
+       int err;
+
+       err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_LINK_STATUS);
+       if (err)
+               return;
+
+       err = qlcnic_issue_cmd(adapter, &cmd);
+       if (err) {
+               dev_info(&adapter->pdev->dev,
+                        "Get Link Status Command failed: 0x%x\n", err);
+               goto out;
+       } else {
+               config = cmd.rsp.arg[3];
+
+               switch (QLC_83XX_SFP_MODULE_TYPE(config)) {
+               case QLC_83XX_MODULE_FIBRE_1000BASE_SX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_LX:
+               case QLC_83XX_MODULE_FIBRE_1000BASE_CX:
+               case QLC_83XX_MODULE_TP_1000BASE_T:
+                       ahw->port_type = QLCNIC_GBE;
+                       break;
+               default:
+                       ahw->port_type = QLCNIC_XGBE;
+               }
+       }
+out:
+       qlcnic_free_mbx_args(&cmd);
+}
+
 int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
 {
        u8 pci_func;
index 3dfe8e27b51c68de0af32af949b096d247e3ccb0..b75a812468569de7728fd9c654b6f1c7e353729f 100644 (file)
@@ -637,6 +637,7 @@ void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *,
 int qlcnic_83xx_set_pauseparam(struct qlcnic_adapter *,
                               struct ethtool_pauseparam *);
 int qlcnic_83xx_test_link(struct qlcnic_adapter *);
+void qlcnic_83xx_get_port_type(struct qlcnic_adapter *adapter);
 int qlcnic_83xx_reg_test(struct qlcnic_adapter *);
 int qlcnic_83xx_get_regs_len(struct qlcnic_adapter *);
 int qlcnic_83xx_get_registers(struct qlcnic_adapter *, u32 *);
index 9a869c15d8bfbfc64b48a831a2b4eb7b38160714..7f7deeaf1cf07913454a13b4f7801c7b3b07545f 100644 (file)
@@ -486,6 +486,9 @@ static int qlcnic_set_link_ksettings(struct net_device *dev,
        u32 ret = 0;
        struct qlcnic_adapter *adapter = netdev_priv(dev);
 
+       if (qlcnic_83xx_check(adapter))
+               qlcnic_83xx_get_port_type(adapter);
+
        if (adapter->ahw->port_type != QLCNIC_GBE)
                return -EOPNOTSUPP;
 
index 513e6c74e1990b6fb2c8b00ee9f5a4b70076115d..24ca7df15d07d48a4214bd5df38edcceb6d284aa 100644 (file)
@@ -296,8 +296,9 @@ qcaspi_receive(struct qcaspi *qca)
 
        /* Allocate rx SKB if we don't have one available. */
        if (!qca->rx_skb) {
-               qca->rx_skb = netdev_alloc_skb(net_dev,
-                                              net_dev->mtu + VLAN_ETH_HLEN);
+               qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
+                                                       net_dev->mtu +
+                                                       VLAN_ETH_HLEN);
                if (!qca->rx_skb) {
                        netdev_dbg(net_dev, "out of RX resources\n");
                        qca->stats.out_of_mem++;
@@ -377,7 +378,7 @@ qcaspi_receive(struct qcaspi *qca)
                                        qca->rx_skb, qca->rx_skb->dev);
                                qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
                                netif_rx_ni(qca->rx_skb);
-                               qca->rx_skb = netdev_alloc_skb(net_dev,
+                               qca->rx_skb = netdev_alloc_skb_ip_align(net_dev,
                                        net_dev->mtu + VLAN_ETH_HLEN);
                                if (!qca->rx_skb) {
                                        netdev_dbg(net_dev, "out of RX resources\n");
@@ -759,7 +760,8 @@ qcaspi_netdev_init(struct net_device *dev)
        if (!qca->rx_buffer)
                return -ENOBUFS;
 
-       qca->rx_skb = netdev_alloc_skb(dev, qca->net_dev->mtu + VLAN_ETH_HLEN);
+       qca->rx_skb = netdev_alloc_skb_ip_align(dev, qca->net_dev->mtu +
+                                               VLAN_ETH_HLEN);
        if (!qca->rx_skb) {
                kfree(qca->rx_buffer);
                netdev_info(qca->net_dev, "Failed to allocate RX sk_buff.\n");
index f68c4db656eda84691b411cee940528a01a2bb62..2d686ccf971b1b6525d7ded8ec5e43b65b67ee6c 100644 (file)
@@ -3220,7 +3220,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        /* MDIO bus init */
        ret = sh_mdio_init(mdp, pd);
        if (ret) {
-               dev_err(&ndev->dev, "failed to initialise MDIO\n");
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "MDIO init failed: %d\n", ret);
                goto out_release;
        }
 
index 7b916aa21bdef18896debc4bdd7384696e50f3a3..4d7fb8af880d0f36189f8475a9859b229a7bd078 100644 (file)
 #include "mcdi.h"
 
 enum {
-       EFX_REV_SIENA_A0 = 0,
-       EFX_REV_HUNT_A0 = 1,
+       /* Revisions 0-2 were Falcon A0, A1 and B0 respectively.
+        * They are not supported by this driver but these revision numbers
+        * form part of the ethtool API for register dumping.
+        */
+       EFX_REV_SIENA_A0 = 3,
+       EFX_REV_HUNT_A0 = 4,
 };
 
 static inline int efx_nic_rev(struct efx_nic *efx)
index cd8c601323905a7ded2504fa69faa54a1c728066..a74c481401c46ee659b1244b0124966cabeafdbd 100644 (file)
@@ -3725,7 +3725,7 @@ static void sysfs_display_ring(void *head, int size, int extend_desc,
                        ep++;
                } else {
                        seq_printf(seq, "%d [0x%x]: 0x%x 0x%x 0x%x 0x%x\n",
-                                  i, (unsigned int)virt_to_phys(ep),
+                                  i, (unsigned int)virt_to_phys(p),
                                   le32_to_cpu(p->des0), le32_to_cpu(p->des1),
                                   le32_to_cpu(p->des2), le32_to_cpu(p->des3));
                        p++;
index 5a90fed0626065613ba59fa7c5f8ca3c2dff6ef3..5b56c24b6ed2e0c45b5a40d32941527bb1539390 100644 (file)
@@ -411,13 +411,14 @@ static int vsw_port_remove(struct vio_dev *vdev)
 
        if (port) {
                del_timer_sync(&port->vio.timer);
+               del_timer_sync(&port->clean_timer);
 
                napi_disable(&port->napi);
+               unregister_netdev(port->dev);
 
                list_del_rcu(&port->list);
 
                synchronize_rcu();
-               del_timer_sync(&port->clean_timer);
                spin_lock_irqsave(&port->vp->lock, flags);
                sunvnet_port_rm_txq_common(port);
                spin_unlock_irqrestore(&port->vp->lock, flags);
@@ -427,7 +428,6 @@ static int vsw_port_remove(struct vio_dev *vdev)
 
                dev_set_drvdata(&vdev->dev, NULL);
 
-               unregister_netdev(port->dev);
                free_netdev(port->dev);
        }
 
index 729a7da90b5bed279d58d72cfc53cfa6fc2e9c80..e6222e535019a076ea0d4cd4c902f12332f079b2 100644 (file)
@@ -1353,9 +1353,10 @@ int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe)
 
        tx_pipe->dma_channel = knav_dma_open_channel(dev,
                                tx_pipe->dma_chan_name, &config);
-       if (IS_ERR_OR_NULL(tx_pipe->dma_channel)) {
+       if (IS_ERR(tx_pipe->dma_channel)) {
                dev_err(dev, "failed opening tx chan(%s)\n",
                        tx_pipe->dma_chan_name);
+               ret = PTR_ERR(tx_pipe->dma_channel);
                goto err;
        }
 
@@ -1673,9 +1674,10 @@ static int netcp_setup_navigator_resources(struct net_device *ndev)
 
        netcp->rx_channel = knav_dma_open_channel(netcp->netcp_device->device,
                                        netcp->dma_chan_name, &config);
-       if (IS_ERR_OR_NULL(netcp->rx_channel)) {
+       if (IS_ERR(netcp->rx_channel)) {
                dev_err(netcp->ndev_dev, "failed opening rx chan(%s\n",
                        netcp->dma_chan_name);
+               ret = PTR_ERR(netcp->rx_channel);
                goto fail;
        }
 
index 897176fc5043bf0da12fe5dcb7a659c269fdf615..dd92950a4615c3aab559c6dc383a4e90ee539160 100644 (file)
@@ -2651,7 +2651,6 @@ static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr)
        case HWTSTAMP_FILTER_NONE:
                cpts_rx_enable(cpts, 0);
                break;
-       case HWTSTAMP_FILTER_ALL:
        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
        case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
index 8716b8c07febf5669b5fe21d78f1b68b4d10ea3f..6f3c805f72118b1b04b48cc501b8579caeddf37a 100644 (file)
@@ -1077,7 +1077,7 @@ static int stir421x_patch_device(struct irda_usb_cb *self)
          * are "42101001.sb" or "42101002.sb"
          */
         sprintf(stir421x_fw_name, "4210%4X.sb",
-                self->usbdev->descriptor.bcdDevice);
+               le16_to_cpu(self->usbdev->descriptor.bcdDevice));
         ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev);
         if (ret < 0)
                 return ret;
index b34eaaae03fd3f289aab4a90b11c05c587858ad2..346ad2ff39989d3da4cacc6ec1965ca882c475cd 100644 (file)
@@ -789,10 +789,12 @@ static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
  */
 static struct lock_class_key macvlan_netdev_addr_lock_key;
 
-#define ALWAYS_ON_FEATURES \
-       (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | NETIF_F_LLTX | \
+#define ALWAYS_ON_OFFLOADS \
+       (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \
         NETIF_F_GSO_ROBUST)
 
+#define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX)
+
 #define MACVLAN_FEATURES \
        (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
         NETIF_F_GSO | NETIF_F_TSO | NETIF_F_UFO | NETIF_F_LRO | \
@@ -827,6 +829,7 @@ static int macvlan_init(struct net_device *dev)
        dev->features           |= ALWAYS_ON_FEATURES;
        dev->hw_features        |= NETIF_F_LRO;
        dev->vlan_features      = lowerdev->vlan_features & MACVLAN_FEATURES;
+       dev->vlan_features      |= ALWAYS_ON_OFFLOADS;
        dev->gso_max_size       = lowerdev->gso_max_size;
        dev->gso_max_segs       = lowerdev->gso_max_segs;
        dev->hard_header_len    = lowerdev->hard_header_len;
index 963838d4fac12428e0c01f88537a72b4a2fd8703..599ce24c514f1b0eb1e8a6df1e3a0362f53bee26 100644 (file)
@@ -122,10 +122,9 @@ int mdio_mux_init(struct device *dev,
        pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
        if (pb == NULL) {
                ret_val = -ENOMEM;
-               goto err_parent_bus;
+               goto err_pb_kz;
        }
 
-
        pb->switch_data = data;
        pb->switch_fn = switch_fn;
        pb->current_child = -1;
@@ -154,6 +153,7 @@ int mdio_mux_init(struct device *dev,
                cb->mii_bus = mdiobus_alloc();
                if (!cb->mii_bus) {
                        ret_val = -ENOMEM;
+                       devm_kfree(dev, cb);
                        of_node_put(child_bus_node);
                        break;
                }
@@ -170,7 +170,6 @@ int mdio_mux_init(struct device *dev,
                        mdiobus_free(cb->mii_bus);
                        devm_kfree(dev, cb);
                } else {
-                       of_node_get(child_bus_node);
                        cb->next = pb->children;
                        pb->children = cb;
                }
@@ -181,9 +180,11 @@ int mdio_mux_init(struct device *dev,
                return 0;
        }
 
+       devm_kfree(dev, pb);
+err_pb_kz:
        /* balance the reference of_mdio_find_bus() took */
-       put_device(&pb->mii_bus->dev);
-
+       if (!mux_bus)
+               put_device(&parent_bus->dev);
 err_parent_bus:
        of_node_put(parent_bus_node);
        return ret_val;
index a898e5c4ef1b465768c3216fc1985382c23eba89..8e73f5f36e7120a5aa28b6e0dfb992eca3330e3e 100644 (file)
@@ -364,9 +364,6 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
 
        mutex_init(&bus->mdio_lock);
 
-       if (bus->reset)
-               bus->reset(bus);
-
        /* de-assert bus level PHY GPIO resets */
        if (bus->num_reset_gpios > 0) {
                bus->reset_gpiod = devm_kcalloc(&bus->dev,
@@ -396,6 +393,9 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
                }
        }
 
+       if (bus->reset)
+               bus->reset(bus);
+
        for (i = 0; i < PHY_MAX_ADDR; i++) {
                if ((bus->phy_mask & (1 << i)) == 0) {
                        struct phy_device *phydev;
index c4f1c363e24b89404c6834312074f8a4451ded50..9df3c1ffff355c491ab7f0a38bdddd0276cfff92 100644 (file)
@@ -310,8 +310,8 @@ static int get_mac_address(struct usbnet *dev, unsigned char *data)
        int rd_mac_len = 0;
 
        netdev_dbg(dev->net, "get_mac_address:\n\tusbnet VID:%0x PID:%0x\n",
-                  dev->udev->descriptor.idVendor,
-                  dev->udev->descriptor.idProduct);
+                  le16_to_cpu(dev->udev->descriptor.idVendor),
+                  le16_to_cpu(dev->udev->descriptor.idProduct));
 
        memset(mac_addr, 0, sizeof(mac_addr));
        rd_mac_len = control_read(dev, REQUEST_READ, 0,
index d7165767ca9d380ed4ab03e0ac592a8ee3a69040..8f923a147fa93117296312c59fdc6761fef50f3c 100644 (file)
@@ -1196,6 +1196,8 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx */
        {QMI_FIXED_INTF(0x1199, 0x9079, 8)},    /* Sierra Wireless EM74xx */
        {QMI_FIXED_INTF(0x1199, 0x9079, 10)},   /* Sierra Wireless EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x907b, 8)},    /* Sierra Wireless EM74xx */
+       {QMI_FIXED_INTF(0x1199, 0x907b, 10)},   /* Sierra Wireless EM74xx */
        {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
        {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)},    /* Alcatel L800MA */
        {QMI_FIXED_INTF(0x2357, 0x0201, 4)},    /* TP-LINK HSUPA Modem MA180 */
index 765400b62168436b278d8a09fa0dd1fd8566bcb7..2dfca96a63b60283b89efab676932a711024a499 100644 (file)
@@ -681,7 +681,7 @@ static int smsc95xx_set_features(struct net_device *netdev,
        if (ret < 0)
                return ret;
 
-       if (features & NETIF_F_HW_CSUM)
+       if (features & NETIF_F_IP_CSUM)
                read_buf |= Tx_COE_EN_;
        else
                read_buf &= ~Tx_COE_EN_;
@@ -1279,12 +1279,19 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
 
        spin_lock_init(&pdata->mac_cr_lock);
 
+       /* LAN95xx devices do not alter the computed checksum of 0 to 0xffff.
+        * RFC 2460, ipv6 UDP calculated checksum yields a result of zero must
+        * be changed to 0xffff. RFC 768, ipv4 UDP computed checksum is zero,
+        * it is transmitted as all ones. The zero transmitted checksum means
+        * transmitter generated no checksum. Hence, enable csum offload only
+        * for ipv4 packets.
+        */
        if (DEFAULT_TX_CSUM_ENABLE)
-               dev->net->features |= NETIF_F_HW_CSUM;
+               dev->net->features |= NETIF_F_IP_CSUM;
        if (DEFAULT_RX_CSUM_ENABLE)
                dev->net->features |= NETIF_F_RXCSUM;
 
-       dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+       dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 
        smsc95xx_init_mac_address(dev);
 
index 25bc764ae7dc4c4dc9a5e6cb4f17f89f62464f4c..d1c7029ded7cefef468eb035f971b969da612bf5 100644 (file)
@@ -2962,6 +2962,11 @@ vmxnet3_force_close(struct vmxnet3_adapter *adapter)
        /* we need to enable NAPI, otherwise dev_close will deadlock */
        for (i = 0; i < adapter->num_rx_queues; i++)
                napi_enable(&adapter->rx_queue[i].napi);
+       /*
+        * Need to clear the quiesce bit to ensure that vmxnet3_close
+        * can quiesce the device properly
+        */
+       clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
        dev_close(adapter->netdev);
 }
 
index ceda5861da780bc64b6070acec7f37de9a8fa3e5..db882493875cd97d30ac5a2b26a764a5b65d9e2e 100644 (file)
@@ -989,6 +989,7 @@ static u32 vrf_fib_table(const struct net_device *dev)
 
 static int vrf_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
+       kfree_skb(skb);
        return 0;
 }
 
@@ -998,7 +999,7 @@ static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook,
 {
        struct net *net = dev_net(dev);
 
-       if (NF_HOOK(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) < 0)
+       if (nf_hook(pf, hook, net, NULL, skb, dev, NULL, vrf_rcv_finish) != 1)
                skb = NULL;    /* kfree_skb(skb) handled by nf code */
 
        return skb;
index 6ffc482550c1d24f9b795f1ab3951101fd901f1c..7b61adb6270c99f8c70f1efa7575b1bb62d96f45 100644 (file)
@@ -1934,8 +1934,7 @@ abort_transaction_no_dev_fatal:
        xennet_disconnect_backend(info);
        xennet_destroy_queues(info);
  out:
-       unregister_netdev(info->netdev);
-       xennet_free_netdev(info->netdev);
+       device_unregister(&dev->dev);
        return err;
 }
 
index 70e689bf1cad286869922764ccd52f1872e92524..dca7165fabcf9ce5df19fee1007e8da8bd794e21 100644 (file)
@@ -1754,6 +1754,10 @@ nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg)
        dev_info(ctrl->ctrl.device,
                "NVME-FC{%d}: resetting controller\n", ctrl->cnum);
 
+       /* stop the queues on error, cleanup is in reset thread */
+       if (ctrl->queue_count > 1)
+               nvme_stop_queues(&ctrl->ctrl);
+
        if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RECONNECTING)) {
                dev_err(ctrl->ctrl.device,
                        "NVME-FC{%d}: error_recovery: Couldn't change state "
@@ -2720,6 +2724,12 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
        unsigned long flags;
        int ret, idx;
 
+       if (!(rport->remoteport.port_role &
+           (FC_PORT_ROLE_NVME_DISCOVERY | FC_PORT_ROLE_NVME_TARGET))) {
+               ret = -EBADR;
+               goto out_fail;
+       }
+
        ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
        if (!ctrl) {
                ret = -ENOMEM;
index fed803232edccbdf63139d89028c694efff52409..4c2ff2bb26bcd7c615e40ae777327a3ba401cf3d 100644 (file)
@@ -1506,6 +1506,11 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
        if (dev->cmb) {
                iounmap(dev->cmb);
                dev->cmb = NULL;
+               if (dev->cmbsz) {
+                       sysfs_remove_file_from_group(&dev->ctrl.device->kobj,
+                                                    &dev_attr_cmb.attr, NULL);
+                       dev->cmbsz = 0;
+               }
        }
 }
 
@@ -1779,6 +1784,7 @@ static void nvme_pci_disable(struct nvme_dev *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev->dev);
 
+       nvme_release_cmb(dev);
        pci_free_irq_vectors(pdev);
 
        if (pci_is_enabled(pdev)) {
@@ -2184,7 +2190,6 @@ static void nvme_remove(struct pci_dev *pdev)
        nvme_dev_disable(dev, true);
        nvme_dev_remove_admin(dev);
        nvme_free_queues(dev, 0);
-       nvme_release_cmb(dev);
        nvme_release_prp_pools(dev);
        nvme_dev_unmap(dev);
        nvme_put_ctrl(&dev->ctrl);
index cf90713043da01ea7180d227feb2895da3653f49..eb9399ac97cff2d5bba89457f6a828238854b98a 100644 (file)
@@ -529,6 +529,12 @@ fail:
 }
 EXPORT_SYMBOL_GPL(nvmet_req_init);
 
+void nvmet_req_uninit(struct nvmet_req *req)
+{
+       percpu_ref_put(&req->sq->ref);
+}
+EXPORT_SYMBOL_GPL(nvmet_req_uninit);
+
 static inline bool nvmet_cc_en(u32 cc)
 {
        return cc & 0x1;
index 62eba29c85fb9b5101d4a974a9392dbb2e71c72d..2006fae61980643d2c42f4d34926aaa11f5f05bc 100644 (file)
@@ -517,9 +517,7 @@ nvmet_fc_queue_to_cpu(struct nvmet_fc_tgtport *tgtport, int qid)
 {
        int cpu, idx, cnt;
 
-       if (!(tgtport->ops->target_features &
-                       NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED) ||
-           tgtport->ops->max_hw_queues == 1)
+       if (tgtport->ops->max_hw_queues == 1)
                return WORK_CPU_UNBOUND;
 
        /* Simple cpu selection based on qid modulo active cpu count */
index 15551ef79c8c4568a6f611b6e9ba9d736127825b..294a6611fb249164e8d321147823e708cfe8a1d1 100644 (file)
@@ -698,7 +698,6 @@ static struct nvmet_fc_target_template tgttemplate = {
        .dma_boundary           = FCLOOP_DMABOUND_4G,
        /* optional features */
        .target_features        = NVMET_FCTGTFEAT_CMD_IN_ISR |
-                                 NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED |
                                  NVMET_FCTGTFEAT_OPDONE_IN_ISR,
        /* sizes of additional private data for data structures */
        .target_priv_sz         = sizeof(struct fcloop_tport),
index 7cb77ba5993b98e0974a66a7712961c434677a7f..cfc5c7fb0ab78411f8d6e96ab7ffaaad241b6244 100644 (file)
@@ -261,6 +261,7 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req);
 
 bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
                struct nvmet_sq *sq, struct nvmet_fabrics_ops *ops);
+void nvmet_req_uninit(struct nvmet_req *req);
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
 
 void nvmet_cq_setup(struct nvmet_ctrl *ctrl, struct nvmet_cq *cq, u16 qid,
index 99c69018a35f4419b3dc3a14576c373c044e661a..9e45cde633767be2176770c7ebd71a90b3ca3094 100644 (file)
@@ -567,6 +567,7 @@ static void nvmet_rdma_read_data_done(struct ib_cq *cq, struct ib_wc *wc)
        rsp->n_rdma = 0;
 
        if (unlikely(wc->status != IB_WC_SUCCESS)) {
+               nvmet_req_uninit(&rsp->req);
                nvmet_rdma_release_rsp(rsp);
                if (wc->status != IB_WC_WR_FLUSH_ERR) {
                        pr_info("RDMA READ for CQE 0x%p failed with status %s (%d).\n",
index 3080d9dd031d14f27553b8596dc4d2dc0248bdfa..43bd69dceabfd36b43368366b8afdc9fa2b30106 100644 (file)
@@ -507,6 +507,9 @@ void *__unflatten_device_tree(const void *blob,
 
        /* Allocate memory for the expanded device tree */
        mem = dt_alloc(size + 4, __alignof__(struct device_node));
+       if (!mem)
+               return NULL;
+
        memset(mem, 0, size);
 
        *(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);
index 4dec07ea510f5fd67f38fa798727bdffef6c3168..d507c3569a88acac9e796f1f172f412e5386347f 100644 (file)
@@ -197,7 +197,7 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
        const struct of_device_id *i;
 
        for (i = __reservedmem_of_table; i < &__rmem_of_table_sentinel; i++) {
-               int const (*initfn)(struct reserved_mem *rmem) = i->data;
+               reservedmem_of_init_fn initfn = i->data;
                const char *compat = i->compatible;
 
                if (!of_flat_dt_is_compatible(rmem->fdt_node, compat))
index 14bde0db8c245680fd010bf2f0aa39093af5a4c2..5b10b50f8686f953a5fe476f3131b0d8a42307bb 100644 (file)
@@ -538,6 +538,7 @@ struct powercap_zone *powercap_register_zone(
 
        power_zone->id = result;
        idr_init(&power_zone->idr);
+       result = -ENOMEM;
        power_zone->name = kstrdup(name, GFP_KERNEL);
        if (!power_zone->name)
                goto err_name_alloc;
index b3de973a62607de6812615e81ac1d00bce5c1f1a..9dca53df35845cc64366a5428d9927bff7f28220 100644 (file)
@@ -1088,7 +1088,7 @@ static u32 rtc_handler(void *context)
        }
        spin_unlock_irqrestore(&rtc_lock, flags);
 
-       pm_wakeup_event(dev, 0);
+       pm_wakeup_hard_event(dev);
        acpi_clear_event(ACPI_EVENT_RTC);
        acpi_disable_event(ACPI_EVENT_RTC, 0);
        return ACPI_INTERRUPT_HANDLED;
index e443b0d0b23612efec3800a5468e36e58ef7f8d3..34b9ad6b31438fb8864a9068d7f72294722da169 100644 (file)
@@ -35,7 +35,7 @@ static struct bus_type ccwgroup_bus_type;
 static void __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
 {
        int i;
-       char str[8];
+       char str[16];
 
        for (i = 0; i < gdev->count; i++) {
                sprintf(str, "cdev%d", i);
@@ -238,7 +238,7 @@ static void ccwgroup_release(struct device *dev)
 
 static int __ccwgroup_create_symlinks(struct ccwgroup_device *gdev)
 {
-       char str[8];
+       char str[16];
        int i, rc;
 
        for (i = 0; i < gdev->count; i++) {
index f33ce85776190ab938548dccbc84fb311d3703fd..1d595d17bf11f6b529eca2caafc494721130b32c 100644 (file)
@@ -11,7 +11,7 @@
 #include "qdio.h"
 
 /* that gives us 15 characters in the text event views */
-#define QDIO_DBF_LEN   16
+#define QDIO_DBF_LEN   32
 
 extern debug_info_t *qdio_dbf_setup;
 extern debug_info_t *qdio_dbf_error;
index f6aa21176d89780e9e745f9045255ff37f1cf788..30bc6105aac3731f2bfad5ffd0d4f14f07f9d291 100644 (file)
@@ -701,6 +701,7 @@ enum qeth_discipline_id {
 };
 
 struct qeth_discipline {
+       const struct device_type *devtype;
        void (*start_poll)(struct ccw_device *, int, unsigned long);
        qdio_handler_t *input_handler;
        qdio_handler_t *output_handler;
@@ -875,6 +876,9 @@ extern struct qeth_discipline qeth_l2_discipline;
 extern struct qeth_discipline qeth_l3_discipline;
 extern const struct attribute_group *qeth_generic_attr_groups[];
 extern const struct attribute_group *qeth_osn_attr_groups[];
+extern const struct attribute_group qeth_device_attr_group;
+extern const struct attribute_group qeth_device_blkt_group;
+extern const struct device_type qeth_generic_devtype;
 extern struct workqueue_struct *qeth_wq;
 
 int qeth_card_hw_is_reachable(struct qeth_card *);
index 38114a8d56e00f471360ab400767dcb8ba8a1a7b..fc6d85f2b38d60d4c1b62bd169776d5cfcabcc52 100644 (file)
@@ -5530,10 +5530,12 @@ void qeth_core_free_discipline(struct qeth_card *card)
        card->discipline = NULL;
 }
 
-static const struct device_type qeth_generic_devtype = {
+const struct device_type qeth_generic_devtype = {
        .name = "qeth_generic",
        .groups = qeth_generic_attr_groups,
 };
+EXPORT_SYMBOL_GPL(qeth_generic_devtype);
+
 static const struct device_type qeth_osn_devtype = {
        .name = "qeth_osn",
        .groups = qeth_osn_attr_groups,
@@ -5659,23 +5661,22 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
                goto err_card;
        }
 
-       if (card->info.type == QETH_CARD_TYPE_OSN)
-               gdev->dev.type = &qeth_osn_devtype;
-       else
-               gdev->dev.type = &qeth_generic_devtype;
-
        switch (card->info.type) {
        case QETH_CARD_TYPE_OSN:
        case QETH_CARD_TYPE_OSM:
                rc = qeth_core_load_discipline(card, QETH_DISCIPLINE_LAYER2);
                if (rc)
                        goto err_card;
+
+               gdev->dev.type = (card->info.type != QETH_CARD_TYPE_OSN)
+                                       ? card->discipline->devtype
+                                       : &qeth_osn_devtype;
                rc = card->discipline->setup(card->gdev);
                if (rc)
                        goto err_disc;
-       case QETH_CARD_TYPE_OSD:
-       case QETH_CARD_TYPE_OSX:
+               break;
        default:
+               gdev->dev.type = &qeth_generic_devtype;
                break;
        }
 
@@ -5731,8 +5732,10 @@ static int qeth_core_set_online(struct ccwgroup_device *gdev)
                if (rc)
                        goto err;
                rc = card->discipline->setup(card->gdev);
-               if (rc)
+               if (rc) {
+                       qeth_core_free_discipline(card);
                        goto err;
+               }
        }
        rc = card->discipline->set_online(gdev);
 err:
index 75b29fd2fcf4eab64e82b23b1183fe88211d97ba..db6a285d41e033674706543c2353c0312046e331 100644 (file)
@@ -413,12 +413,16 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
 
        if (card->options.layer2 == newdis)
                goto out;
-       else {
-               card->info.mac_bits  = 0;
-               if (card->discipline) {
-                       card->discipline->remove(card->gdev);
-                       qeth_core_free_discipline(card);
-               }
+       if (card->info.type == QETH_CARD_TYPE_OSM) {
+               /* fixed layer, can't switch */
+               rc = -EOPNOTSUPP;
+               goto out;
+       }
+
+       card->info.mac_bits = 0;
+       if (card->discipline) {
+               card->discipline->remove(card->gdev);
+               qeth_core_free_discipline(card);
        }
 
        rc = qeth_core_load_discipline(card, newdis);
@@ -426,6 +430,8 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
                goto out;
 
        rc = card->discipline->setup(card->gdev);
+       if (rc)
+               qeth_core_free_discipline(card);
 out:
        mutex_unlock(&card->discipline_mutex);
        return rc ? rc : count;
@@ -703,10 +709,11 @@ static struct attribute *qeth_blkt_device_attrs[] = {
        &dev_attr_inter_jumbo.attr,
        NULL,
 };
-static struct attribute_group qeth_device_blkt_group = {
+const struct attribute_group qeth_device_blkt_group = {
        .name = "blkt",
        .attrs = qeth_blkt_device_attrs,
 };
+EXPORT_SYMBOL_GPL(qeth_device_blkt_group);
 
 static struct attribute *qeth_device_attrs[] = {
        &dev_attr_state.attr,
@@ -726,9 +733,10 @@ static struct attribute *qeth_device_attrs[] = {
        &dev_attr_switch_attrs.attr,
        NULL,
 };
-static struct attribute_group qeth_device_attr_group = {
+const struct attribute_group qeth_device_attr_group = {
        .attrs = qeth_device_attrs,
 };
+EXPORT_SYMBOL_GPL(qeth_device_attr_group);
 
 const struct attribute_group *qeth_generic_attr_groups[] = {
        &qeth_device_attr_group,
index 29d9fb3890ad570826db6d54b1396c149f83fcb5..0d59f9a45ea9e3c52ba4eee9cbc7b37b433dd449 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "qeth_core.h"
 
+extern const struct attribute_group *qeth_l2_attr_groups[];
+
 int qeth_l2_create_device_attributes(struct device *);
 void qeth_l2_remove_device_attributes(struct device *);
 void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card);
index 1b07f382d74c955974d138271bdce2bbbf594f63..bd2df62a5cdf50a85243a878ed98d4d1784b9106 100644 (file)
@@ -880,11 +880,21 @@ static int qeth_l2_stop(struct net_device *dev)
        return 0;
 }
 
+static const struct device_type qeth_l2_devtype = {
+       .name = "qeth_layer2",
+       .groups = qeth_l2_attr_groups,
+};
+
 static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
 {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+       int rc;
 
-       qeth_l2_create_device_attributes(&gdev->dev);
+       if (gdev->dev.type == &qeth_generic_devtype) {
+               rc = qeth_l2_create_device_attributes(&gdev->dev);
+               if (rc)
+                       return rc;
+       }
        INIT_LIST_HEAD(&card->vid_list);
        hash_init(card->mac_htable);
        card->options.layer2 = 1;
@@ -896,7 +906,8 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 {
        struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
 
-       qeth_l2_remove_device_attributes(&cgdev->dev);
+       if (cgdev->dev.type == &qeth_generic_devtype)
+               qeth_l2_remove_device_attributes(&cgdev->dev);
        qeth_set_allowed_threads(card, 0, 1);
        wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
 
@@ -954,7 +965,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
        case QETH_CARD_TYPE_OSN:
                card->dev = alloc_netdev(0, "osn%d", NET_NAME_UNKNOWN,
                                         ether_setup);
-               card->dev->flags |= IFF_NOARP;
                break;
        default:
                card->dev = alloc_etherdev(0);
@@ -969,9 +979,12 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
        card->dev->min_mtu = 64;
        card->dev->max_mtu = ETH_MAX_MTU;
        card->dev->netdev_ops = &qeth_l2_netdev_ops;
-       card->dev->ethtool_ops =
-               (card->info.type != QETH_CARD_TYPE_OSN) ?
-               &qeth_l2_ethtool_ops : &qeth_l2_osn_ops;
+       if (card->info.type == QETH_CARD_TYPE_OSN) {
+               card->dev->ethtool_ops = &qeth_l2_osn_ops;
+               card->dev->flags |= IFF_NOARP;
+       } else {
+               card->dev->ethtool_ops = &qeth_l2_ethtool_ops;
+       }
        card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
        if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
                card->dev->hw_features = NETIF_F_SG;
@@ -1269,6 +1282,7 @@ static int qeth_l2_control_event(struct qeth_card *card,
 }
 
 struct qeth_discipline qeth_l2_discipline = {
+       .devtype = &qeth_l2_devtype,
        .start_poll = qeth_qdio_start_poll,
        .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
        .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
index 687972356d6b00f8776cb332e31b1ae0063183a5..9696baa49e2d4409062be4338ea383472a7d4ab0 100644 (file)
@@ -269,3 +269,11 @@ void qeth_l2_setup_bridgeport_attrs(struct qeth_card *card)
        } else
                qeth_bridgeport_an_set(card, 0);
 }
+
+const struct attribute_group *qeth_l2_attr_groups[] = {
+       &qeth_device_attr_group,
+       &qeth_device_blkt_group,
+       /* l2 specific, see l2_{create,remove}_device_attributes(): */
+       &qeth_l2_bridgeport_attr_group,
+       NULL,
+};
index 6e0354ef4b8629827e4c8ef40b9d569bc11e354b..d8df1e6351636250ea534cf17527c8fb198435f2 100644 (file)
@@ -3039,8 +3039,13 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
 static int qeth_l3_probe_device(struct ccwgroup_device *gdev)
 {
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+       int rc;
 
-       qeth_l3_create_device_attributes(&gdev->dev);
+       rc = qeth_l3_create_device_attributes(&gdev->dev);
+       if (rc)
+               return rc;
+       hash_init(card->ip_htable);
+       hash_init(card->ip_mc_htable);
        card->options.layer2 = 0;
        card->info.hwtrap = 0;
        return 0;
@@ -3306,6 +3311,7 @@ static int qeth_l3_control_event(struct qeth_card *card,
 }
 
 struct qeth_discipline qeth_l3_discipline = {
+       .devtype = &qeth_generic_devtype,
        .start_poll = qeth_qdio_start_poll,
        .input_handler = (qdio_handler_t *) qeth_qdio_input_handler,
        .output_handler = (qdio_handler_t *) qeth_qdio_output_handler,
index 2a76ea78a0bf1ae9f62508e701cca07a9f690d1f..b18fe2014cf2195a193186c08c956dc8e5cfe7e3 100644 (file)
@@ -87,7 +87,7 @@ struct vq_info_block {
 } __packed;
 
 struct virtio_feature_desc {
-       __u32 features;
+       __le32 features;
        __u8 index;
 } __packed;
 
index c052104e523ee4f7212ce3c70be08509f8f7df5b..a011c5dbf214055315c6bbdd73c814fd752c2bbe 100644 (file)
@@ -5,6 +5,7 @@
 config CXLFLASH
        tristate "Support for IBM CAPI Flash"
        depends on PCI && SCSI && CXL && EEH
+       select IRQ_POLL
        default m
        help
          Allows CAPI Accelerated IO to Flash
index a808e8ef1d08d433ba4b703353d486a4f5ef3564..234352da5c3cebeff0d523bbe3842d297ddd8272 100644 (file)
@@ -407,11 +407,12 @@ unlock:
  * can_queue. Eventually we will hit the point where we run
  * on all reserved structs.
  */
-static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
+static bool fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
 {
        struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
        unsigned long flags;
        int can_queue;
+       bool changed = false;
 
        spin_lock_irqsave(lport->host->host_lock, flags);
 
@@ -427,9 +428,11 @@ static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
        if (!can_queue)
                can_queue = 1;
        lport->host->can_queue = can_queue;
+       changed = true;
 
 unlock:
        spin_unlock_irqrestore(lport->host->host_lock, flags);
+       return changed;
 }
 
 /*
@@ -1896,11 +1899,11 @@ int fc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc_cmd)
 
        if (!fc_fcp_lport_queue_ready(lport)) {
                if (lport->qfull) {
-                       fc_fcp_can_queue_ramp_down(lport);
-                       shost_printk(KERN_ERR, lport->host,
-                                    "libfc: queue full, "
-                                    "reducing can_queue to %d.\n",
-                                    lport->host->can_queue);
+                       if (fc_fcp_can_queue_ramp_down(lport))
+                               shost_printk(KERN_ERR, lport->host,
+                                            "libfc: queue full, "
+                                            "reducing can_queue to %d.\n",
+                                            lport->host->can_queue);
                }
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
index 944b32ca493144f3fc66d625cc2f960ad484373d..1c55408ac718a94f9aa622210a0ebf96a9896137 100644 (file)
@@ -294,6 +294,7 @@ int lpfc_selective_reset(struct lpfc_hba *);
 void lpfc_reset_barrier(struct lpfc_hba *);
 int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
 int lpfc_sli_brdkill(struct lpfc_hba *);
+int lpfc_sli_chipset_init(struct lpfc_hba *phba);
 int lpfc_sli_brdreset(struct lpfc_hba *);
 int lpfc_sli_brdrestart(struct lpfc_hba *);
 int lpfc_sli_hba_setup(struct lpfc_hba *);
index 1487406aea778411476b1d95f6c454c790c559bb..c7962dae4dab8c7130dcb46fa1b7d45dac0509eb 100644 (file)
@@ -630,7 +630,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,
                                                NLP_EVT_DEVICE_RECOVERY);
                        spin_lock_irq(shost->host_lock);
                        ndlp->nlp_flag &= ~NLP_NVMET_RECOV;
-                       spin_lock_irq(shost->host_lock);
+                       spin_unlock_irq(shost->host_lock);
                }
        }
 
index 90ae354a9c458c9151b03f6bdff444a248d0da0e..4b1eb98c228df823a986f5568f8b948a7b2ef9bf 100644 (file)
@@ -3602,6 +3602,13 @@ lpfc_get_wwpn(struct lpfc_hba *phba)
        LPFC_MBOXQ_t *mboxq;
        MAILBOX_t *mb;
 
+       if (phba->sli_rev < LPFC_SLI_REV4) {
+               /* Reset the port first */
+               lpfc_sli_brdrestart(phba);
+               rc = lpfc_sli_chipset_init(phba);
+               if (rc)
+                       return (uint64_t)-1;
+       }
 
        mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
                                                GFP_KERNEL);
@@ -8847,7 +8854,7 @@ lpfc_sli4_queue_unset(struct lpfc_hba *phba)
                lpfc_wq_destroy(phba, phba->sli4_hba.nvmels_wq);
 
        /* Unset ELS work queue */
-       if (phba->sli4_hba.els_cq)
+       if (phba->sli4_hba.els_wq)
                lpfc_wq_destroy(phba, phba->sli4_hba.els_wq);
 
        /* Unset unsolicited receive queue */
index 94434e621c335e678ad2aa1c3301b967cb15a210..0488580eea12eecd0c2767bc6ad5c11a014ac46d 100644 (file)
@@ -764,7 +764,6 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba)
        lpfc_tgttemplate.max_sgl_segments = phba->cfg_nvme_seg_cnt + 1;
        lpfc_tgttemplate.max_hw_queues = phba->cfg_nvme_io_channel;
        lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP |
-                                          NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED |
                                           NVMET_FCTGTFEAT_CMD_IN_ISR |
                                           NVMET_FCTGTFEAT_OPDONE_IN_ISR;
 
index cf19f4976f5fb6338509d85a6e9c4624b9b882b5..2a4fc00dfa9bdc7dbe42d5bed00935abd0a9e398 100644 (file)
@@ -4204,13 +4204,16 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
        /* Reset HBA */
        lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
                        "0325 Reset HBA Data: x%x x%x\n",
-                       phba->pport->port_state, psli->sli_flag);
+                       (phba->pport) ? phba->pport->port_state : 0,
+                       psli->sli_flag);
 
        /* perform board reset */
        phba->fc_eventTag = 0;
        phba->link_events = 0;
-       phba->pport->fc_myDID = 0;
-       phba->pport->fc_prevDID = 0;
+       if (phba->pport) {
+               phba->pport->fc_myDID = 0;
+               phba->pport->fc_prevDID = 0;
+       }
 
        /* Turn off parity checking and serr during the physical reset */
        pci_read_config_word(phba->pcidev, PCI_COMMAND, &cfg_value);
@@ -4336,7 +4339,8 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba)
        /* Restart HBA */
        lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
                        "0337 Restart HBA Data: x%x x%x\n",
-                       phba->pport->port_state, psli->sli_flag);
+                       (phba->pport) ? phba->pport->port_state : 0,
+                       psli->sli_flag);
 
        word0 = 0;
        mb = (MAILBOX_t *) &word0;
@@ -4350,7 +4354,7 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba)
        readl(to_slim); /* flush */
 
        /* Only skip post after fc_ffinit is completed */
-       if (phba->pport->port_state)
+       if (phba->pport && phba->pport->port_state)
                word0 = 1;      /* This is really setting up word1 */
        else
                word0 = 0;      /* This is really setting up word1 */
@@ -4359,7 +4363,8 @@ lpfc_sli_brdrestart_s3(struct lpfc_hba *phba)
        readl(to_slim); /* flush */
 
        lpfc_sli_brdreset(phba);
-       phba->pport->stopped = 0;
+       if (phba->pport)
+               phba->pport->stopped = 0;
        phba->link_state = LPFC_INIT_START;
        phba->hba_flag = 0;
        spin_unlock_irq(&phba->hbalock);
@@ -4446,7 +4451,7 @@ lpfc_sli_brdrestart(struct lpfc_hba *phba)
  * iteration, the function will restart the HBA again. The function returns
  * zero if HBA successfully restarted else returns negative error code.
  **/
-static int
+int
 lpfc_sli_chipset_init(struct lpfc_hba *phba)
 {
        uint32_t status, i = 0;
index a4aadf5f4dc61e9d80a5f1382fd63f11d169dd0d..1cc814f1505a3c149133a0c8c5c2f5f556c056d4 100644 (file)
@@ -3770,9 +3770,6 @@ static long pmcraid_ioctl_passthrough(
                        pmcraid_err("couldn't build passthrough ioadls\n");
                        goto out_free_cmd;
                }
-       } else if (request_size < 0) {
-               rc = -EINVAL;
-               goto out_free_cmd;
        }
 
        /* If data is being written into the device, copy the data from user
index 40aeb6bb96a2afd11c3264b7ea0004110033e2d1..07ee88200e91cfc072eed5506c6eca0974dda67f 100644 (file)
@@ -259,7 +259,7 @@ struct qedf_io_log {
        uint16_t task_id;
        uint32_t port_id; /* Remote port fabric ID */
        int lun;
-       char op; /* SCSI CDB */
+       unsigned char op; /* SCSI CDB */
        uint8_t lba[4];
        unsigned int bufflen; /* SCSI buffer length */
        unsigned int sg_count; /* Number of SG elements */
index c505d41f6dc843825fb52fabaaca33e5dd25d1ce..90627033bde600c551af700004858a18ddadaa6c 100644 (file)
@@ -109,7 +109,7 @@ retry_els:
        did = fcport->rdata->ids.port_id;
        sid = fcport->sid;
 
-       __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, sid, did,
+       __fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, did, sid,
                           FC_TYPE_ELS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ |
                           FC_FC_SEQ_INIT, 0);
 
index cceddd995a4bf46605ae94143cfcff9df693fb83..a5c97342fd5d2bc5f9826d34974e8d7b7c285dd3 100644 (file)
@@ -2895,7 +2895,7 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
        slowpath_params.drv_minor = QEDF_DRIVER_MINOR_VER;
        slowpath_params.drv_rev = QEDF_DRIVER_REV_VER;
        slowpath_params.drv_eng = QEDF_DRIVER_ENG_VER;
-       memcpy(slowpath_params.name, "qedf", QED_DRV_VER_STR_SIZE);
+       strncpy(slowpath_params.name, "qedf", QED_DRV_VER_STR_SIZE);
        rc = qed_ops->common->slowpath_start(qedf->cdev, &slowpath_params);
        if (rc) {
                QEDF_ERR(&(qedf->dbg_ctx), "Cannot start slowpath.\n");
index 7bfbcfa7af40b7df8bff2a0f38728621ee9f13e0..61cdd99ae41ec7e45a0cf0de604be4e169172368 100644 (file)
@@ -763,6 +763,8 @@ struct scsi_device *__scsi_device_lookup(struct Scsi_Host *shost,
        struct scsi_device *sdev;
 
        list_for_each_entry(sdev, &shost->__devices, siblings) {
+               if (sdev->sdev_state == SDEV_DEL)
+                       continue;
                if (sdev->channel == channel && sdev->id == id &&
                                sdev->lun ==lun)
                        return sdev;
index 814a4bd8405dca1a4897edd7f4cb66a163cb2545..e31f1cc90b815b28a332d1a6915c82e19519a62f 100644 (file)
@@ -30,6 +30,7 @@
 #include <scsi/scsi_driver.h>
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport.h> /* __scsi_init_queue() */
 #include <scsi/scsi_dh.h>
 
 #include <trace/events/scsi.h>
index b6195fdf0d0033c7ec24afb9cff100cd5dcf0978..22e98a90468c8e35d50e0a1f0da0f73c177084f5 100644 (file)
@@ -49,7 +49,7 @@ static const struct of_device_id sun_top_ctrl_match[] = {
        { .compatible = "brcm,bcm7420-sun-top-ctrl", },
        { .compatible = "brcm,bcm7425-sun-top-ctrl", },
        { .compatible = "brcm,bcm7429-sun-top-ctrl", },
-       { .compatible = "brcm,bcm7425-sun-top-ctrl", },
+       { .compatible = "brcm,bcm7435-sun-top-ctrl", },
        { .compatible = "brcm,brcmstb-sun-top-ctrl", },
        { }
 };
index 357a5d8f8da004d611058b24baa698fc3fbf159c..a5b86a28f343bb9c90c575310848b94855fcc3b4 100644 (file)
@@ -2,8 +2,9 @@ menu "i.MX SoC drivers"
 
 config IMX7_PM_DOMAINS
        bool "i.MX7 PM domains"
-       select PM_GENERIC_DOMAINS
        depends on SOC_IMX7D || (COMPILE_TEST && OF)
+       depends on PM
+       select PM_GENERIC_DOMAINS
        default y if SOC_IMX7D
 
 endmenu
index ecebe2eecc3aac5058de888817b719f42934d526..026182d3b27c1405a9b875d529795a2e8295a0aa 100644 (file)
@@ -413,7 +413,7 @@ static int of_channel_match_helper(struct device_node *np, const char *name,
  * @name:      slave channel name
  * @config:    dma configuration parameters
  *
- * Returns pointer to appropriate DMA channel on success or NULL.
+ * Returns pointer to appropriate DMA channel on success or error.
  */
 void *knav_dma_open_channel(struct device *dev, const char *name,
                                        struct knav_dma_cfg *config)
diff --git a/drivers/staging/android/ion/devicetree.txt b/drivers/staging/android/ion/devicetree.txt
deleted file mode 100644 (file)
index 1687152..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-Ion Memory Manager
-
-Ion is a memory manager that allows for sharing of buffers via dma-buf.
-Ion allows for different types of allocation via an abstraction called
-a 'heap'. A heap represents a specific type of memory. Each heap has
-a different type. There can be multiple instances of the same heap
-type.
-
-Specific heap instances are tied to heap IDs. Heap IDs are not to be specified
-in the devicetree.
-
-Required properties for Ion
-
-- compatible: "linux,ion" PLUS a compatible property for the device
-
-All child nodes of a linux,ion node are interpreted as heaps
-
-required properties for heaps
-
-- compatible: compatible string for a heap type PLUS a compatible property
-for the specific instance of the heap. Current heap types
--- linux,ion-heap-system
--- linux,ion-heap-system-contig
--- linux,ion-heap-carveout
--- linux,ion-heap-chunk
--- linux,ion-heap-dma
--- linux,ion-heap-custom
-
-Optional properties
-- memory-region: A phandle to a memory region. Required for DMA heap type
-(see reserved-memory.txt for details on the reservation)
-
-Example:
-
-       ion {
-               compatbile = "hisilicon,ion", "linux,ion";
-
-               ion-system-heap {
-                       compatbile = "hisilicon,system-heap", "linux,ion-heap-system"
-               };
-
-               ion-camera-region {
-                       compatible = "hisilicon,camera-heap", "linux,ion-heap-dma"
-                       memory-region = <&camera_region>;
-               };
-
-               ion-fb-region {
-                       compatbile = "hisilicon,fb-heap", "linux,ion-heap-dma"
-                       memory-region = <&fb_region>;
-               };
-       }
index 522bd62c102eafe592349006206f2916ad67b15b..8611adf3bb2e9e8f42d5b210db9a0d20670085c2 100644 (file)
@@ -376,7 +376,6 @@ int send_request(
        rc = ssi_power_mgr_runtime_get(&drvdata->plat_dev->dev);
        if (rc != 0) {
                SSI_LOG_ERR("ssi_power_mgr_runtime_get returned %x\n",rc);
-               spin_unlock_bh(&req_mgr_h->hw_lock);
                return rc;
        }
 #endif
index 2e325cb747ae97bace5497964e27c76b49fe1f80..730fd6d4db33e9bb9fc607b0a6d1cbc26f7079b2 100644 (file)
@@ -12,6 +12,7 @@ config FSL_DPAA2
 config FSL_DPAA2_ETH
        tristate "Freescale DPAA2 Ethernet"
        depends on FSL_DPAA2 && FSL_MC_DPIO
+       depends on NETDEVICES && ETHERNET
        ---help---
          Ethernet driver for Freescale DPAA2 SoCs, using the
          Freescale MC bus driver
index 4723a0bd5067595fdbc38850887cdc69a947c59e..1c6ed5b2a6f96d1d227fb72d9b84f37776c4ece3 100644 (file)
@@ -97,8 +97,9 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val)
 
        switch (variable) {
        case HW_VAR_BSSID:
-               rtl92e_writel(dev, BSSIDR, ((u32 *)(val))[0]);
-               rtl92e_writew(dev, BSSIDR+2, ((u16 *)(val+2))[0]);
+               /* BSSIDR 2 byte alignment */
+               rtl92e_writew(dev, BSSIDR, *(u16 *)val);
+               rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(val + 2));
                break;
 
        case HW_VAR_MEDIA_STATUS:
@@ -624,7 +625,7 @@ void rtl92e_get_eeprom_size(struct net_device *dev)
        struct r8192_priv *priv = rtllib_priv(dev);
 
        RT_TRACE(COMP_INIT, "===========>%s()\n", __func__);
-       curCR = rtl92e_readl(dev, EPROM_CMD);
+       curCR = rtl92e_readw(dev, EPROM_CMD);
        RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD,
                 curCR);
        priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 :
@@ -961,8 +962,8 @@ static void _rtl92e_net_update(struct net_device *dev)
        rtl92e_config_rate(dev, &rate_config);
        priv->dot11CurrentPreambleMode = PREAMBLE_AUTO;
         priv->basic_rate = rate_config &= 0x15f;
-       rtl92e_writel(dev, BSSIDR, ((u32 *)net->bssid)[0]);
-       rtl92e_writew(dev, BSSIDR+4, ((u16 *)net->bssid)[2]);
+       rtl92e_writew(dev, BSSIDR, *(u16 *)net->bssid);
+       rtl92e_writel(dev, BSSIDR + 2, *(u32 *)(net->bssid + 2));
 
        if (priv->rtllib->iw_mode == IW_MODE_ADHOC) {
                rtl92e_writew(dev, ATIMWND, 2);
@@ -1182,8 +1183,7 @@ void  rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
                          struct cb_desc *cb_desc, struct sk_buff *skb)
 {
        struct r8192_priv *priv = rtllib_priv(dev);
-       dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len,
-                        PCI_DMA_TODEVICE);
+       dma_addr_t mapping;
        struct tx_fwinfo_8190pci *pTxFwInfo;
 
        pTxFwInfo = (struct tx_fwinfo_8190pci *)skb->data;
@@ -1194,8 +1194,6 @@ void  rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
        pTxFwInfo->Short = _rtl92e_query_is_short(pTxFwInfo->TxHT,
                                                  pTxFwInfo->TxRate, cb_desc);
 
-       if (pci_dma_mapping_error(priv->pdev, mapping))
-               netdev_err(dev, "%s(): DMA Mapping error\n", __func__);
        if (cb_desc->bAMPDUEnable) {
                pTxFwInfo->AllowAggregation = 1;
                pTxFwInfo->RxMF = cb_desc->ampdu_factor;
@@ -1230,6 +1228,14 @@ void  rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc,
        }
 
        memset((u8 *)pdesc, 0, 12);
+
+       mapping = pci_map_single(priv->pdev, skb->data, skb->len,
+                                PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(priv->pdev, mapping)) {
+               netdev_err(dev, "%s(): DMA Mapping error\n", __func__);
+               return;
+       }
+
        pdesc->LINIP = 0;
        pdesc->CmdInit = 1;
        pdesc->Offset = sizeof(struct tx_fwinfo_8190pci) + 8;
index 48bbd9e8a52f3444ff345a934a0721faf556ccc7..dcc4eb691889245e65927172a6e97a206d05fa6c 100644 (file)
@@ -306,11 +306,6 @@ static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr,
        pTsCommonInfo->TClasNum = TCLAS_Num;
 }
 
-static bool IsACValid(unsigned int tid)
-{
-       return tid < 7;
-}
-
 bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
           u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs)
 {
@@ -328,12 +323,6 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
        if (ieee->current_network.qos_data.supported == 0) {
                UP = 0;
        } else {
-               if (!IsACValid(TID)) {
-                       netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n",
-                                   __func__, TID);
-                       return false;
-               }
-
                switch (TID) {
                case 0:
                case 3:
@@ -351,6 +340,10 @@ bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS,
                case 7:
                        UP = 7;
                        break;
+               default:
+                       netdev_warn(ieee->dev, "%s(): TID(%d) is not valid\n",
+                                   __func__, TID);
+                       return false;
                }
        }
 
index 5e7a61f24f8dc38daea774986696ec6cc1d9ce9d..36c3189fc4b7f6f981ca683dd53267a5f9e541c3 100644 (file)
@@ -3531,7 +3531,6 @@ int rtw_wdev_alloc(struct adapter *padapter, struct device *dev)
                pwdev_priv->power_mgmt = true;
        else
                pwdev_priv->power_mgmt = false;
-       kfree((u8 *)wdev);
 
        return ret;
 
index 2cee9a952c9b8d164fc3f94140ea6cb63e982d7a..4a356e509fe450b4260ac3b49ec001d4fa9aea7a 100644 (file)
@@ -264,22 +264,36 @@ static void fusb302_debugfs_exit(const struct fusb302_chip *chip) { }
 
 #define FUSB302_RESUME_RETRY 10
 #define FUSB302_RESUME_RETRY_SLEEP 50
-static int fusb302_i2c_write(struct fusb302_chip *chip,
-                            u8 address, u8 data)
+
+static bool fusb302_is_suspended(struct fusb302_chip *chip)
 {
        int retry_cnt;
-       int ret = 0;
 
-       atomic_set(&chip->i2c_busy, 1);
        for (retry_cnt = 0; retry_cnt < FUSB302_RESUME_RETRY; retry_cnt++) {
                if (atomic_read(&chip->pm_suspend)) {
-                       pr_err("fusb302_i2c: pm suspend, retry %d/%d\n",
-                              retry_cnt + 1, FUSB302_RESUME_RETRY);
+                       dev_err(chip->dev, "i2c: pm suspend, retry %d/%d\n",
+                               retry_cnt + 1, FUSB302_RESUME_RETRY);
                        msleep(FUSB302_RESUME_RETRY_SLEEP);
                } else {
-                       break;
+                       return false;
                }
        }
+
+       return true;
+}
+
+static int fusb302_i2c_write(struct fusb302_chip *chip,
+                            u8 address, u8 data)
+{
+       int ret = 0;
+
+       atomic_set(&chip->i2c_busy, 1);
+
+       if (fusb302_is_suspended(chip)) {
+               atomic_set(&chip->i2c_busy, 0);
+               return -ETIMEDOUT;
+       }
+
        ret = i2c_smbus_write_byte_data(chip->i2c_client, address, data);
        if (ret < 0)
                fusb302_log(chip, "cannot write 0x%02x to 0x%02x, ret=%d",
@@ -292,21 +306,17 @@ static int fusb302_i2c_write(struct fusb302_chip *chip,
 static int fusb302_i2c_block_write(struct fusb302_chip *chip, u8 address,
                                   u8 length, const u8 *data)
 {
-       int retry_cnt;
        int ret = 0;
 
        if (length <= 0)
                return ret;
        atomic_set(&chip->i2c_busy, 1);
-       for (retry_cnt = 0; retry_cnt < FUSB302_RESUME_RETRY; retry_cnt++) {
-               if (atomic_read(&chip->pm_suspend)) {
-                       pr_err("fusb302_i2c: pm suspend, retry %d/%d\n",
-                              retry_cnt + 1, FUSB302_RESUME_RETRY);
-                       msleep(FUSB302_RESUME_RETRY_SLEEP);
-               } else {
-                       break;
-               }
+
+       if (fusb302_is_suspended(chip)) {
+               atomic_set(&chip->i2c_busy, 0);
+               return -ETIMEDOUT;
        }
+
        ret = i2c_smbus_write_i2c_block_data(chip->i2c_client, address,
                                             length, data);
        if (ret < 0)
@@ -320,19 +330,15 @@ static int fusb302_i2c_block_write(struct fusb302_chip *chip, u8 address,
 static int fusb302_i2c_read(struct fusb302_chip *chip,
                            u8 address, u8 *data)
 {
-       int retry_cnt;
        int ret = 0;
 
        atomic_set(&chip->i2c_busy, 1);
-       for (retry_cnt = 0; retry_cnt < FUSB302_RESUME_RETRY; retry_cnt++) {
-               if (atomic_read(&chip->pm_suspend)) {
-                       pr_err("fusb302_i2c: pm suspend, retry %d/%d\n",
-                              retry_cnt + 1, FUSB302_RESUME_RETRY);
-                       msleep(FUSB302_RESUME_RETRY_SLEEP);
-               } else {
-                       break;
-               }
+
+       if (fusb302_is_suspended(chip)) {
+               atomic_set(&chip->i2c_busy, 0);
+               return -ETIMEDOUT;
        }
+
        ret = i2c_smbus_read_byte_data(chip->i2c_client, address);
        *data = (u8)ret;
        if (ret < 0)
@@ -345,33 +351,31 @@ static int fusb302_i2c_read(struct fusb302_chip *chip,
 static int fusb302_i2c_block_read(struct fusb302_chip *chip, u8 address,
                                  u8 length, u8 *data)
 {
-       int retry_cnt;
        int ret = 0;
 
        if (length <= 0)
                return ret;
        atomic_set(&chip->i2c_busy, 1);
-       for (retry_cnt = 0; retry_cnt < FUSB302_RESUME_RETRY; retry_cnt++) {
-               if (atomic_read(&chip->pm_suspend)) {
-                       pr_err("fusb302_i2c: pm suspend, retry %d/%d\n",
-                              retry_cnt + 1, FUSB302_RESUME_RETRY);
-                       msleep(FUSB302_RESUME_RETRY_SLEEP);
-               } else {
-                       break;
-               }
+
+       if (fusb302_is_suspended(chip)) {
+               atomic_set(&chip->i2c_busy, 0);
+               return -ETIMEDOUT;
        }
+
        ret = i2c_smbus_read_i2c_block_data(chip->i2c_client, address,
                                            length, data);
        if (ret < 0) {
                fusb302_log(chip, "cannot block read 0x%02x, len=%d, ret=%d",
                            address, length, ret);
-               return ret;
+               goto done;
        }
        if (ret != length) {
                fusb302_log(chip, "only read %d/%d bytes from 0x%02x",
                            ret, length, address);
-               return -EIO;
+               ret = -EIO;
        }
+
+done:
        atomic_set(&chip->i2c_busy, 0);
 
        return ret;
@@ -489,7 +493,7 @@ static int tcpm_init(struct tcpc_dev *dev)
        ret = fusb302_i2c_read(chip, FUSB_REG_STATUS0, &data);
        if (ret < 0)
                return ret;
-       chip->vbus_present = !!(FUSB_REG_STATUS0 & FUSB_REG_STATUS0_VBUSOK);
+       chip->vbus_present = !!(data & FUSB_REG_STATUS0_VBUSOK);
        ret = fusb302_i2c_read(chip, FUSB_REG_DEVICE_ID, &data);
        if (ret < 0)
                return ret;
@@ -1025,7 +1029,7 @@ static int fusb302_pd_send_message(struct fusb302_chip *chip,
        buf[pos++] = FUSB302_TKN_SYNC1;
        buf[pos++] = FUSB302_TKN_SYNC2;
 
-       len = pd_header_cnt(msg->header) * 4;
+       len = pd_header_cnt_le(msg->header) * 4;
        /* plug 2 for header */
        len += 2;
        if (len > 0x1F) {
@@ -1481,7 +1485,7 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip,
                                     (u8 *)&msg->header);
        if (ret < 0)
                return ret;
-       len = pd_header_cnt(msg->header) * 4;
+       len = pd_header_cnt_le(msg->header) * 4;
        /* add 4 to length to include the CRC */
        if (len > PD_MAX_PAYLOAD * 4) {
                fusb302_log(chip, "PD message too long %d", len);
@@ -1663,14 +1667,12 @@ static int init_gpio(struct fusb302_chip *chip)
        if (ret < 0) {
                fusb302_log(chip,
                            "cannot set GPIO Int_N to input, ret=%d", ret);
-               gpio_free(chip->gpio_int_n);
                return ret;
        }
        ret = gpio_to_irq(chip->gpio_int_n);
        if (ret < 0) {
                fusb302_log(chip,
                            "cannot request IRQ for GPIO Int_N, ret=%d", ret);
-               gpio_free(chip->gpio_int_n);
                return ret;
        }
        chip->gpio_int_n_irq = ret;
@@ -1787,11 +1789,13 @@ static const struct of_device_id fusb302_dt_match[] = {
        {.compatible = "fcs,fusb302"},
        {},
 };
+MODULE_DEVICE_TABLE(of, fusb302_dt_match);
 
 static const struct i2c_device_id fusb302_i2c_device_id[] = {
        {"typec_fusb302", 0},
        {},
 };
+MODULE_DEVICE_TABLE(i2c, fusb302_i2c_device_id);
 
 static const struct dev_pm_ops fusb302_pm_ops = {
        .suspend = fusb302_pm_suspend,
index 8d97bdb95f2385c7450cf093b8d7042d17520c15..510ef7279900617d5057f559b414239f99a36e03 100644 (file)
@@ -92,6 +92,16 @@ static inline unsigned int pd_header_type_le(__le16 header)
        return pd_header_type(le16_to_cpu(header));
 }
 
+static inline unsigned int pd_header_msgid(u16 header)
+{
+       return (header >> PD_HEADER_ID_SHIFT) & PD_HEADER_ID_MASK;
+}
+
+static inline unsigned int pd_header_msgid_le(__le16 header)
+{
+       return pd_header_msgid(le16_to_cpu(header));
+}
+
 #define PD_MAX_PAYLOAD         7
 
 struct pd_message {
index dba172e0e0d1faf52c9e9c287ef6c7e5be2e11da..d92259f8de0a835ad2a634d079e6d08ab327f654 100644 (file)
@@ -22,6 +22,9 @@
  * VDM object is minimum of VDM header + 6 additional data objects.
  */
 
+#define VDO_MAX_OBJECTS                6
+#define VDO_MAX_SIZE           (VDO_MAX_OBJECTS + 1)
+
 /*
  * VDM header
  * ----------
@@ -34,7 +37,6 @@
  * <5>      :: reserved (SVDM), command type (UVDM)
  * <4:0>    :: command
  */
-#define VDO_MAX_SIZE 7
 #define VDO(vid, type, custom)                         \
        (((vid) << 16) |                                \
         ((type) << 15) |                               \
index 5e5be74c7850032e4bd40705e1628e5cb14bb344..df72d8b01e730d5b2a9de183dbf9d64f662226f6 100644 (file)
@@ -425,7 +425,7 @@ static const struct regmap_config tcpci_regmap_config = {
        .max_register = 0x7F, /* 0x80 .. 0xFF are vendor defined */
 };
 
-const struct tcpc_config tcpci_tcpc_config = {
+static const struct tcpc_config tcpci_tcpc_config = {
        .type = TYPEC_PORT_DFP,
        .default_role = TYPEC_SINK,
 };
index abba655ba00a3469537c61070a747d276aa06cfa..20eb4ebcf8c3dba29f03fa58fa09169c281bf27c 100644 (file)
@@ -238,6 +238,7 @@ struct tcpm_port {
        unsigned int hard_reset_count;
        bool pd_capable;
        bool explicit_contract;
+       unsigned int rx_msgid;
 
        /* Partner capabilities/requests */
        u32 sink_request;
@@ -251,6 +252,8 @@ struct tcpm_port {
        unsigned int nr_src_pdo;
        u32 snk_pdo[PDO_MAX_OBJECTS];
        unsigned int nr_snk_pdo;
+       u32 snk_vdo[VDO_MAX_OBJECTS];
+       unsigned int nr_snk_vdo;
 
        unsigned int max_snk_mv;
        unsigned int max_snk_ma;
@@ -997,6 +1000,7 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
        struct pd_mode_data *modep;
        int rlen = 0;
        u16 svid;
+       int i;
 
        tcpm_log(port, "Rx VDM cmd 0x%x type %d cmd %d len %d",
                 p0, cmd_type, cmd, cnt);
@@ -1007,6 +1011,14 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
        case CMDT_INIT:
                switch (cmd) {
                case CMD_DISCOVER_IDENT:
+                       /* 6.4.4.3.1: Only respond as UFP (device) */
+                       if (port->data_role == TYPEC_DEVICE &&
+                           port->nr_snk_vdo) {
+                               for (i = 0; i <  port->nr_snk_vdo; i++)
+                                       response[i + 1]
+                                               = cpu_to_le32(port->snk_vdo[i]);
+                               rlen = port->nr_snk_vdo + 1;
+                       }
                        break;
                case CMD_DISCOVER_SVID:
                        break;
@@ -1415,6 +1427,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
                        break;
                case SOFT_RESET_SEND:
                        port->message_id = 0;
+                       port->rx_msgid = -1;
                        if (port->pwr_role == TYPEC_SOURCE)
                                next_state = SRC_SEND_CAPABILITIES;
                        else
@@ -1503,6 +1516,22 @@ static void tcpm_pd_rx_handler(struct work_struct *work)
                 port->attached);
 
        if (port->attached) {
+               enum pd_ctrl_msg_type type = pd_header_type_le(msg->header);
+               unsigned int msgid = pd_header_msgid_le(msg->header);
+
+               /*
+                * USB PD standard, 6.6.1.2:
+                * "... if MessageID value in a received Message is the
+                * same as the stored value, the receiver shall return a
+                * GoodCRC Message with that MessageID value and drop
+                * the Message (this is a retry of an already received
+                * Message). Note: this shall not apply to the Soft_Reset
+                * Message which always has a MessageID value of zero."
+                */
+               if (msgid == port->rx_msgid && type != PD_CTRL_SOFT_RESET)
+                       goto done;
+               port->rx_msgid = msgid;
+
                /*
                 * If both ends believe to be DFP/host, we have a data role
                 * mismatch.
@@ -1520,6 +1549,7 @@ static void tcpm_pd_rx_handler(struct work_struct *work)
                }
        }
 
+done:
        mutex_unlock(&port->lock);
        kfree(event);
 }
@@ -1719,8 +1749,7 @@ static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo)
        }
        ma = min(ma, port->max_snk_ma);
 
-       /* XXX: Any other flags need to be set? */
-       flags = 0;
+       flags = RDO_USB_COMM | RDO_NO_SUSPEND;
 
        /* Set mismatch bit if offered power is less than operating power */
        mw = ma * mv / 1000;
@@ -1957,6 +1986,12 @@ static void tcpm_reset_port(struct tcpm_port *port)
        port->attached = false;
        port->pd_capable = false;
 
+       /*
+        * First Rx ID should be 0; set this to a sentinel of -1 so that
+        * we can check tcpm_pd_rx_handler() if we had seen it before.
+        */
+       port->rx_msgid = -1;
+
        port->tcpc->set_pd_rx(port->tcpc, false);
        tcpm_init_vbus(port);   /* also disables charging */
        tcpm_init_vconn(port);
@@ -2170,6 +2205,7 @@ static void run_state_machine(struct tcpm_port *port)
                port->pwr_opmode = TYPEC_PWR_MODE_USB;
                port->caps_count = 0;
                port->message_id = 0;
+               port->rx_msgid = -1;
                port->explicit_contract = false;
                tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
                break;
@@ -2329,6 +2365,7 @@ static void run_state_machine(struct tcpm_port *port)
                typec_set_pwr_opmode(port->typec_port, TYPEC_PWR_MODE_USB);
                port->pwr_opmode = TYPEC_PWR_MODE_USB;
                port->message_id = 0;
+               port->rx_msgid = -1;
                port->explicit_contract = false;
                tcpm_set_state(port, SNK_DISCOVERY, 0);
                break;
@@ -2496,6 +2533,7 @@ static void run_state_machine(struct tcpm_port *port)
        /* Soft_Reset states */
        case SOFT_RESET:
                port->message_id = 0;
+               port->rx_msgid = -1;
                tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
                if (port->pwr_role == TYPEC_SOURCE)
                        tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
@@ -2504,6 +2542,7 @@ static void run_state_machine(struct tcpm_port *port)
                break;
        case SOFT_RESET_SEND:
                port->message_id = 0;
+               port->rx_msgid = -1;
                if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
                        tcpm_set_state_cond(port, hard_reset_state(port), 0);
                else
@@ -2568,6 +2607,14 @@ static void run_state_machine(struct tcpm_port *port)
                break;
        case PR_SWAP_SRC_SNK_SOURCE_OFF:
                tcpm_set_cc(port, TYPEC_CC_RD);
+               /*
+                * USB-PD standard, 6.2.1.4, Port Power Role:
+                * "During the Power Role Swap Sequence, for the initial Source
+                * Port, the Port Power Role field shall be set to Sink in the
+                * PS_RDY Message indicating that the initial Source’s power
+                * supply is turned off"
+                */
+               tcpm_set_pwr_role(port, TYPEC_SINK);
                if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) {
                        tcpm_set_state(port, ERROR_RECOVERY, 0);
                        break;
@@ -2575,7 +2622,6 @@ static void run_state_machine(struct tcpm_port *port)
                tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
                break;
        case PR_SWAP_SRC_SNK_SINK_ON:
-               tcpm_set_pwr_role(port, TYPEC_SINK);
                tcpm_swap_complete(port, 0);
                tcpm_set_state(port, SNK_STARTUP, 0);
                break;
@@ -2587,8 +2633,15 @@ static void run_state_machine(struct tcpm_port *port)
        case PR_SWAP_SNK_SRC_SOURCE_ON:
                tcpm_set_cc(port, tcpm_rp_cc(port));
                tcpm_set_vbus(port, true);
-               tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
+               /*
+                * USB PD standard, 6.2.1.4:
+                * "Subsequent Messages initiated by the Policy Engine,
+                * such as the PS_RDY Message sent to indicate that Vbus
+                * is ready, will have the Port Power Role field set to
+                * Source."
+                */
                tcpm_set_pwr_role(port, TYPEC_SOURCE);
+               tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
                tcpm_swap_complete(port, 0);
                tcpm_set_state(port, SRC_STARTUP, 0);
                break;
@@ -3292,6 +3345,20 @@ static int tcpm_copy_pdos(u32 *dest_pdo, const u32 *src_pdo,
        return nr_pdo;
 }
 
+static int tcpm_copy_vdos(u32 *dest_vdo, const u32 *src_vdo,
+                         unsigned int nr_vdo)
+{
+       unsigned int i;
+
+       if (nr_vdo > VDO_MAX_OBJECTS)
+               nr_vdo = VDO_MAX_OBJECTS;
+
+       for (i = 0; i < nr_vdo; i++)
+               dest_vdo[i] = src_vdo[i];
+
+       return nr_vdo;
+}
+
 void tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
                                     unsigned int nr_pdo)
 {
@@ -3382,6 +3449,8 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
                                          tcpc->config->nr_src_pdo);
        port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, tcpc->config->snk_pdo,
                                          tcpc->config->nr_snk_pdo);
+       port->nr_snk_vdo = tcpm_copy_vdos(port->snk_vdo, tcpc->config->snk_vdo,
+                                         tcpc->config->nr_snk_vdo);
 
        port->max_snk_mv = tcpc->config->max_snk_mv;
        port->max_snk_ma = tcpc->config->max_snk_ma;
index 969b365e65497775f4481478641ab9f07cbbe2c4..19c307d31a5a39267abe546451c89f953ccc0945 100644 (file)
@@ -60,6 +60,9 @@ struct tcpc_config {
        const u32 *snk_pdo;
        unsigned int nr_snk_pdo;
 
+       const u32 *snk_vdo;
+       unsigned int nr_snk_vdo;
+
        unsigned int max_snk_mv;
        unsigned int max_snk_ma;
        unsigned int max_snk_mw;
index 988ee61fb4a7be9d4248c97c89f99ab947465fb0..d04db3f555192d58a9e1f0d9357b0b25578f1a91 100644 (file)
@@ -502,8 +502,15 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
         */
        sg_init_table(scatterlist, num_pages);
        /* Now set the pages for each scatterlist */
-       for (i = 0; i < num_pages; i++)
-               sg_set_page(scatterlist + i, pages[i], PAGE_SIZE, 0);
+       for (i = 0; i < num_pages; i++) {
+               unsigned int len = PAGE_SIZE - offset;
+
+               if (len > count)
+                       len = count;
+               sg_set_page(scatterlist + i, pages[i], len, offset);
+               offset = 0;
+               count -= len;
+       }
 
        dma_buffers = dma_map_sg(g_dev,
                                 scatterlist,
@@ -524,20 +531,20 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
                u32 addr = sg_dma_address(sg);
 
                /* Note: addrs is the address + page_count - 1
-                * The firmware expects the block to be page
+                * The firmware expects blocks after the first to be page-
                 * aligned and a multiple of the page size
                 */
                WARN_ON(len == 0);
-               WARN_ON(len & ~PAGE_MASK);
-               WARN_ON(addr & ~PAGE_MASK);
+               WARN_ON(i && (i != (dma_buffers - 1)) && (len & ~PAGE_MASK));
+               WARN_ON(i && (addr & ~PAGE_MASK));
                if (k > 0 &&
-                   ((addrs[k - 1] & PAGE_MASK) |
-                       ((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT)
-                   == addr) {
-                       addrs[k - 1] += (len >> PAGE_SHIFT);
-               } else {
-                       addrs[k++] = addr | ((len >> PAGE_SHIFT) - 1);
-               }
+                   ((addrs[k - 1] & PAGE_MASK) +
+                    (((addrs[k - 1] & ~PAGE_MASK) + 1) << PAGE_SHIFT))
+                   == (addr & PAGE_MASK))
+                       addrs[k - 1] += ((len + PAGE_SIZE - 1) >> PAGE_SHIFT);
+               else
+                       addrs[k++] = (addr & PAGE_MASK) |
+                               (((len + PAGE_SIZE - 1) >> PAGE_SHIFT) - 1);
        }
 
        /* Partial cache lines (fragments) require special measures */
index 2330a4eb4e8b71ff30103ba57de63fc868c34726..a6df12d88f90cd097ab88df8d151970243aea26b 100644 (file)
@@ -1,6 +1,7 @@
 # Generic Trusted Execution Environment Configuration
 config TEE
        tristate "Trusted Execution Environment support"
+       depends on HAVE_ARM_SMCCC || COMPILE_TEST
        select DMA_SHARED_BUFFER
        select GENERIC_ALLOCATOR
        help
index 1c196f87e9d967886c88b1ae7fe05cc5f01ed4ee..ff04b7f8549f06f5730afb1cf6334785afab9d05 100644 (file)
@@ -279,7 +279,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                map = kzalloc(sizeof(*map), GFP_KERNEL);
                if (!map) {
                        ret = -ENOMEM;
-                       goto err_map_kobj;
+                       goto err_map;
                }
                kobject_init(&map->kobj, &map_attr_type);
                map->mem = mem;
@@ -289,7 +289,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                        goto err_map_kobj;
                ret = kobject_uevent(&map->kobj, KOBJ_ADD);
                if (ret)
-                       goto err_map;
+                       goto err_map_kobj;
        }
 
        for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
@@ -308,7 +308,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                portio = kzalloc(sizeof(*portio), GFP_KERNEL);
                if (!portio) {
                        ret = -ENOMEM;
-                       goto err_portio_kobj;
+                       goto err_portio;
                }
                kobject_init(&portio->kobj, &portio_attr_type);
                portio->port = port;
@@ -319,7 +319,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
                        goto err_portio_kobj;
                ret = kobject_uevent(&portio->kobj, KOBJ_ADD);
                if (ret)
-                       goto err_portio;
+                       goto err_portio_kobj;
        }
 
        return 0;
index cfc3cff6e8d5901be03e89d1423c6f66aa6a7d06..8e6ef671be9b60f948e521d4c273228f161cdbb6 100644 (file)
@@ -475,11 +475,11 @@ static void snoop_urb(struct usb_device *udev,
 
        if (userurb) {          /* Async */
                if (when == SUBMIT)
-                       dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+                       dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
                                        "length %u\n",
                                        userurb, ep, t, d, length);
                else
-                       dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
+                       dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
                                        "actual_length %u status %d\n",
                                        userurb, ep, t, d, length,
                                        timeout_or_status);
@@ -1895,7 +1895,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg)
        if (as) {
                int retval;
 
-               snoop(&ps->dev->dev, "reap %p\n", as->userurb);
+               snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
                retval = processcompl(as, (void __user * __user *)arg);
                free_async(as);
                return retval;
@@ -1912,7 +1912,7 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)
 
        as = async_getcompleted(ps);
        if (as) {
-               snoop(&ps->dev->dev, "reap %p\n", as->userurb);
+               snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
                retval = processcompl(as, (void __user * __user *)arg);
                free_async(as);
        } else {
@@ -2043,7 +2043,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg)
        if (as) {
                int retval;
 
-               snoop(&ps->dev->dev, "reap %p\n", as->userurb);
+               snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
                retval = processcompl_compat(as, (void __user * __user *)arg);
                free_async(as);
                return retval;
@@ -2060,7 +2060,7 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar
 
        as = async_getcompleted(ps);
        if (as) {
-               snoop(&ps->dev->dev, "reap %p\n", as->userurb);
+               snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
                retval = processcompl_compat(as, (void __user * __user *)arg);
                free_async(as);
        } else {
@@ -2489,7 +2489,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
 #endif
 
        case USBDEVFS_DISCARDURB:
-               snoop(&dev->dev, "%s: DISCARDURB %p\n", __func__, p);
+               snoop(&dev->dev, "%s: DISCARDURB %pK\n", __func__, p);
                ret = proc_unlinkurb(ps, p);
                break;
 
index 49550790a3cba255df329dd73ca6e08e17a13af7..5dea98358c05c46b09f913fee8b7c48d9f2c4f85 100644 (file)
@@ -1723,7 +1723,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
                if (retval == 0)
                        retval = -EINPROGRESS;
                else if (retval != -EIDRM && retval != -EBUSY)
-                       dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
+                       dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
                                        urb, retval);
                usb_put_dev(udev);
        }
@@ -1890,7 +1890,7 @@ rescan:
                /* kick hcd */
                unlink1(hcd, urb, -ESHUTDOWN);
                dev_dbg (hcd->self.controller,
-                       "shutdown urb %p ep%d%s%s\n",
+                       "shutdown urb %pK ep%d%s%s\n",
                        urb, usb_endpoint_num(&ep->desc),
                        is_in ? "in" : "out",
                        ({      char *s;
@@ -2520,6 +2520,7 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
                hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
                                GFP_KERNEL);
                if (!hcd->bandwidth_mutex) {
+                       kfree(hcd->address0_mutex);
                        kfree(hcd);
                        dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");
                        return NULL;
index 9dca59ef18b3454437da9affb5e6d93619e88ba3..b8bb20d7acdb9f1480009605f10e2f5ae4045ec9 100644 (file)
@@ -362,7 +362,8 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
 }
 
 /* USB 2.0 spec Section 11.24.4.5 */
-static int get_hub_descriptor(struct usb_device *hdev, void *data)
+static int get_hub_descriptor(struct usb_device *hdev,
+               struct usb_hub_descriptor *desc)
 {
        int i, ret, size;
        unsigned dtype;
@@ -378,10 +379,18 @@ static int get_hub_descriptor(struct usb_device *hdev, void *data)
        for (i = 0; i < 3; i++) {
                ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
-                       dtype << 8, 0, data, size,
+                       dtype << 8, 0, desc, size,
                        USB_CTRL_GET_TIMEOUT);
-               if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))
+               if (hub_is_superspeed(hdev)) {
+                       if (ret == size)
+                               return ret;
+               } else if (ret >= USB_DT_HUB_NONVAR_SIZE + 2) {
+                       /* Make sure we have the DeviceRemovable field. */
+                       size = USB_DT_HUB_NONVAR_SIZE + desc->bNbrPorts / 8 + 1;
+                       if (ret < size)
+                               return -EMSGSIZE;
                        return ret;
+               }
        }
        return -EINVAL;
 }
@@ -1313,7 +1322,7 @@ static int hub_configure(struct usb_hub *hub,
        }
        mutex_init(&hub->status_mutex);
 
-       hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
+       hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
                ret = -ENOMEM;
                goto fail;
@@ -1321,13 +1330,19 @@ static int hub_configure(struct usb_hub *hub,
 
        /* Request the entire hub descriptor.
         * hub->descriptor can handle USB_MAXCHILDREN ports,
-        * but the hub can/will return fewer bytes here.
+        * but a (non-SS) hub can/will return fewer bytes here.
         */
        ret = get_hub_descriptor(hdev, hub->descriptor);
        if (ret < 0) {
                message = "can't read hub descriptor";
                goto fail;
-       } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
+       }
+
+       maxchild = USB_MAXCHILDREN;
+       if (hub_is_superspeed(hdev))
+               maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS);
+
+       if (hub->descriptor->bNbrPorts > maxchild) {
                message = "hub has too many ports!";
                ret = -ENODEV;
                goto fail;
index d787f195a9a682c99e6289166d364d9aed110b2b..d563cbcf76cfbfb197aa1e45be1dc5f700102770 100644 (file)
@@ -53,6 +53,9 @@ EXPORT_SYMBOL_GPL(usb_of_get_child_node);
  *
  * Find the companion device from platform bus.
  *
+ * Takes a reference to the returned struct device which needs to be dropped
+ * after use.
+ *
  * Return: On success, a pointer to the companion device, %NULL on failure.
  */
 struct device *usb_of_get_companion_dev(struct device *dev)
index d75cb8c0f7df76ca1c78d1c39de9db17f9039af0..47903d510955b03967da9a125092b6965118c0be 100644 (file)
@@ -338,7 +338,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
        if (!urb || !urb->complete)
                return -EINVAL;
        if (urb->hcpriv) {
-               WARN_ONCE(1, "URB %p submitted while active\n", urb);
+               WARN_ONCE(1, "URB %pK submitted while active\n", urb);
                return -EBUSY;
        }
 
index 72664700b8a25c7d9bcee89c16c68fa6b5792565..12ee23f53cdde17ea924344ff7e84d88cf9881cb 100644 (file)
@@ -107,6 +107,10 @@ static int kdwc3_probe(struct platform_device *pdev)
                return PTR_ERR(kdwc->usbss);
 
        kdwc->clk = devm_clk_get(kdwc->dev, "usb");
+       if (IS_ERR(kdwc->clk)) {
+               dev_err(kdwc->dev, "unable to get usb clock\n");
+               return PTR_ERR(kdwc->clk);
+       }
 
        error = clk_prepare_enable(kdwc->clk);
        if (error < 0) {
index a15ec71d04233a3ac9e93fe5d9063edb0a4d89af..84a2cebfc712023182dbb4622cbc355b3545310d 100644 (file)
@@ -39,6 +39,8 @@
 #define PCI_DEVICE_ID_INTEL_APL                        0x5aaa
 #define PCI_DEVICE_ID_INTEL_KBP                        0xa2b0
 #define PCI_DEVICE_ID_INTEL_GLK                        0x31aa
+#define PCI_DEVICE_ID_INTEL_CNPLP              0x9dee
+#define PCI_DEVICE_ID_INTEL_CNPH               0xa36e
 
 #define PCI_INTEL_BXT_DSM_UUID         "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
 #define PCI_INTEL_BXT_FUNC_PMU_PWR     4
@@ -270,6 +272,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPLP), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPH), },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
        {  }    /* Terminating Entry */
 };
index 6f6f0b3be3ad7a3491d244ff5648a3ef852479c4..aea9a5b948b4beda91988152b80ff666e8890b26 100644 (file)
@@ -1261,14 +1261,24 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
                                __dwc3_gadget_start_isoc(dwc, dep, cur_uf);
                                dep->flags &= ~DWC3_EP_PENDING_REQUEST;
                        }
+                       return 0;
                }
-               return 0;
+
+               if ((dep->flags & DWC3_EP_BUSY) &&
+                   !(dep->flags & DWC3_EP_MISSED_ISOC)) {
+                       WARN_ON_ONCE(!dep->resource_index);
+                       ret = __dwc3_gadget_kick_transfer(dep,
+                                                         dep->resource_index);
+               }
+
+               goto out;
        }
 
        if (!dwc3_calc_trbs_left(dep))
                return 0;
 
        ret = __dwc3_gadget_kick_transfer(dep, 0);
+out:
        if (ret == -EBUSY)
                ret = 0;
 
@@ -3026,6 +3036,15 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
                return IRQ_HANDLED;
        }
 
+       /*
+        * With PCIe legacy interrupt, test shows that top-half irq handler can
+        * be called again after HW interrupt deassertion. Check if bottom-half
+        * irq event handler completes before caching new event to prevent
+        * losing events.
+        */
+       if (evt->flags & DWC3_EVENT_PENDING)
+               return IRQ_HANDLED;
+
        count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
        count &= DWC3_GEVNTCOUNT_MASK;
        if (!count)
index 71dd27c0d7f27daf9d2db08b6a0b72901844ba3f..47dda3450abd9391de37cf19115abfa0b927a402 100644 (file)
@@ -1858,12 +1858,12 @@ static int ffs_func_eps_enable(struct ffs_function *func)
                ep->ep->driver_data = ep;
                ep->ep->desc = ds;
 
-               comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
-                               USB_DT_ENDPOINT_SIZE);
-               ep->ep->maxburst = comp_desc->bMaxBurst + 1;
-
-               if (needs_comp_desc)
+               if (needs_comp_desc) {
+                       comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
+                                       USB_DT_ENDPOINT_SIZE);
+                       ep->ep->maxburst = comp_desc->bMaxBurst + 1;
                        ep->ep->comp_desc = comp_desc;
+               }
 
                ret = usb_ep_enable(ep->ep);
                if (likely(!ret)) {
index 000677c991b0264ee079f46e79be1ab271001c9b..9b0805f55ad79b3a6b12069508ddc583d2765053 100644 (file)
@@ -1256,7 +1256,7 @@ static void gserial_console_exit(void)
        struct gscons_info *info = &gscons_info;
 
        unregister_console(&gserial_cons);
-       if (info->console_thread != NULL)
+       if (!IS_ERR_OR_NULL(info->console_thread))
                kthread_stop(info->console_thread);
        gs_buf_free(&info->con_buf);
 }
index c79081952ea068c770887298ed1c5483f0e61dac..ccabb51cb98da69b4b72d46a59846f3b97e1b8f6 100644 (file)
@@ -2008,7 +2008,7 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc)
                        HUB_CHAR_COMMON_OCPM);
        desc->bNbrPorts = 1;
        desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
-       desc->u.ss.DeviceRemovable = 0xffff;
+       desc->u.ss.DeviceRemovable = 0;
 }
 
 static inline void hub_descriptor(struct usb_hub_descriptor *desc)
@@ -2020,8 +2020,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
                        HUB_CHAR_INDV_PORT_LPSM |
                        HUB_CHAR_COMMON_OCPM);
        desc->bNbrPorts = 1;
-       desc->u.hs.DeviceRemovable[0] = 0xff;
-       desc->u.hs.DeviceRemovable[1] = 0xff;
+       desc->u.hs.DeviceRemovable[0] = 0;
+       desc->u.hs.DeviceRemovable[1] = 0xff;   /* PortPwrCtrlMask */
 }
 
 static int dummy_hub_control(
index bc7b9be12f540cb22dc3a5e9ab93aa49f4c722ef..f1908ea9fbd863f9d693d6a852e154e72087770c 100644 (file)
@@ -384,8 +384,10 @@ static int ehci_platform_resume(struct device *dev)
        }
 
        companion_dev = usb_of_get_companion_dev(hcd->self.controller);
-       if (companion_dev)
+       if (companion_dev) {
                device_pm_wait_for_dev(hcd->self.controller, companion_dev);
+               put_device(companion_dev);
+       }
 
        ehci_resume(hcd, priv->reset_on_resume);
        return 0;
index bfa7fa3d2eea0143b89298b3c722f9627af98fce..7bf78be1fd32503571df68999197008c85b64879 100644 (file)
@@ -1269,7 +1269,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
                        time = 30;
                        break;
                default:
-                       time = 300;
+                       time = 50;
                        break;
                }
 
@@ -1785,6 +1785,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
                pipe = td->pipe;
                pipe_stop(r8a66597, pipe);
 
+               /* Select a different address or endpoint */
                new_td = td;
                do {
                        list_move_tail(&new_td->queue,
@@ -1794,7 +1795,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
                                new_td = td;
                                break;
                        }
-               } while (td != new_td && td->address == new_td->address);
+               } while (td != new_td && td->address == new_td->address &&
+                       td->pipe->info.epnum == new_td->pipe->info.epnum);
 
                start_transfer(r8a66597, new_td);
 
index 5e3e9d4c6956bab71a815a86ef8e658cce12b48e..0dde49c35dd23d858feb2d537840b568fd1c4643 100644 (file)
@@ -419,7 +419,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
        wait_for_completion(cmd->completion);
 
        if (cmd->status == COMP_COMMAND_ABORTED ||
-                       cmd->status == COMP_STOPPED) {
+           cmd->status == COMP_COMMAND_RING_STOPPED) {
                xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
                ret = -ETIME;
        }
index bbe22bcc550a7f2641c8be1f379510c2ba0d9162..1f1687e888d623c33ffe2413fb5584f02c6b733e 100644 (file)
@@ -56,7 +56,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
        }
 
        if (max_packet) {
-               seg->bounce_buf = kzalloc(max_packet, flags | GFP_DMA);
+               seg->bounce_buf = kzalloc(max_packet, flags);
                if (!seg->bounce_buf) {
                        dma_pool_free(xhci->segment_pool, seg->trbs, dma);
                        kfree(seg);
@@ -1724,7 +1724,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
        xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma);
        for (i = 0; i < num_sp; i++) {
                dma_addr_t dma;
-               void *buf = dma_alloc_coherent(dev, xhci->page_size, &dma,
+               void *buf = dma_zalloc_coherent(dev, xhci->page_size, &dma,
                                flags);
                if (!buf)
                        goto fail_sp4;
@@ -2307,10 +2307,11 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
        /* Place limits on the number of roothub ports so that the hub
         * descriptors aren't longer than the USB core will allocate.
         */
-       if (xhci->num_usb3_ports > 15) {
+       if (xhci->num_usb3_ports > USB_SS_MAXPORTS) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_init,
-                               "Limiting USB 3.0 roothub ports to 15.");
-               xhci->num_usb3_ports = 15;
+                               "Limiting USB 3.0 roothub ports to %u.",
+                               USB_SS_MAXPORTS);
+               xhci->num_usb3_ports = USB_SS_MAXPORTS;
        }
        if (xhci->num_usb2_ports > USB_MAXCHILDREN) {
                xhci_dbg_trace(xhci, trace_xhci_dbg_init,
index 7b86508ac8cf522e1143561a6e9a7d8f40f5a964..fcf1f3f63e7af3d60a62675beddca912ac853428 100644 (file)
@@ -52,6 +52,7 @@
 #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI             0x0aa8
 #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI             0x1aa8
 #define PCI_DEVICE_ID_INTEL_APL_XHCI                   0x5aa8
+#define PCI_DEVICE_ID_INTEL_DNV_XHCI                   0x19d0
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -166,7 +167,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
                 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
                 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
                 pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
-                pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI)) {
+                pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+                pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI)) {
                xhci->quirks |= XHCI_PME_STUCK_QUIRK;
        }
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
@@ -175,7 +177,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
        }
        if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
            (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
-            pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
+            pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI ||
+            pdev->device == PCI_DEVICE_ID_INTEL_DNV_XHCI))
                xhci->quirks |= XHCI_MISSING_CAS;
 
        if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
index 7c2a9e7c8e0f2aa4d5cc7f5e413f23ccc75c116d..c04144b25a673a2f2438854ea4183dd7cc0b0fab 100644 (file)
@@ -177,7 +177,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
-               return -ENODEV;
+               return irq;
 
        /*
         * sysdev must point to a device that is known to the system firmware
index 74bf5c60a26075fff92cf74f6d3b2a2d4af4f0d4..03f63f50afb6213d58b498f559021db28f8a4d5a 100644 (file)
@@ -323,7 +323,7 @@ static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
                if (i_cmd->status != COMP_COMMAND_ABORTED)
                        continue;
 
-               i_cmd->status = COMP_STOPPED;
+               i_cmd->status = COMP_COMMAND_RING_STOPPED;
 
                xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
                         i_cmd->command_trb);
@@ -641,8 +641,8 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
        xhci_urb_free_priv(urb_priv);
        usb_hcd_unlink_urb_from_ep(hcd, urb);
        spin_unlock(&xhci->lock);
-       usb_hcd_giveback_urb(hcd, urb, status);
        trace_xhci_urb_giveback(urb);
+       usb_hcd_giveback_urb(hcd, urb, status);
        spin_lock(&xhci->lock);
 }
 
@@ -1380,7 +1380,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
        cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status));
 
        /* If CMD ring stopped we own the trbs between enqueue and dequeue */
-       if (cmd_comp_code == COMP_STOPPED) {
+       if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) {
                complete_all(&xhci->cmd_ring_stop_completion);
                return;
        }
@@ -1436,8 +1436,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
                break;
        case TRB_CMD_NOOP:
                /* Is this an aborted command turned to NO-OP? */
-               if (cmd->status == COMP_STOPPED)
-                       cmd_comp_code = COMP_STOPPED;
+               if (cmd->status == COMP_COMMAND_RING_STOPPED)
+                       cmd_comp_code = COMP_COMMAND_RING_STOPPED;
                break;
        case TRB_RESET_EP:
                WARN_ON(slot_id != TRB_TO_SLOT_ID(
@@ -2677,11 +2677,12 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        union xhci_trb *event_ring_deq;
        irqreturn_t ret = IRQ_NONE;
+       unsigned long flags;
        dma_addr_t deq;
        u64 temp_64;
        u32 status;
 
-       spin_lock(&xhci->lock);
+       spin_lock_irqsave(&xhci->lock, flags);
        /* Check if the xHC generated the interrupt, or the irq is shared */
        status = readl(&xhci->op_regs->status);
        if (status == ~(u32)0) {
@@ -2707,12 +2708,9 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
         */
        status |= STS_EINT;
        writel(status, &xhci->op_regs->status);
-       /* FIXME when MSI-X is supported and there are multiple vectors */
-       /* Clear the MSI-X event interrupt status */
 
-       if (hcd->irq) {
+       if (!hcd->msi_enabled) {
                u32 irq_pending;
-               /* Acknowledge the PCI interrupt */
                irq_pending = readl(&xhci->ir_set->irq_pending);
                irq_pending |= IMAN_IP;
                writel(irq_pending, &xhci->ir_set->irq_pending);
@@ -2757,7 +2755,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
        ret = IRQ_HANDLED;
 
 out:
-       spin_unlock(&xhci->lock);
+       spin_unlock_irqrestore(&xhci->lock, flags);
 
        return ret;
 }
index 2d1310220832c3792f7290f1095e8bd23ea71fd2..30f47d92a6104ef52ae5e782e1f305fa0a517cad 100644 (file)
@@ -359,9 +359,10 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
                /* fall back to msi*/
                ret = xhci_setup_msi(xhci);
 
-       if (!ret)
-               /* hcd->irq is 0, we have MSI */
+       if (!ret) {
+               hcd->msi_enabled = 1;
                return 0;
+       }
 
        if (!pdev->irq) {
                xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
@@ -1763,7 +1764,7 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
 
        switch (*cmd_status) {
        case COMP_COMMAND_ABORTED:
-       case COMP_STOPPED:
+       case COMP_COMMAND_RING_STOPPED:
                xhci_warn(xhci, "Timeout while waiting for configure endpoint command\n");
                ret = -ETIME;
                break;
@@ -1813,7 +1814,7 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
 
        switch (*cmd_status) {
        case COMP_COMMAND_ABORTED:
-       case COMP_STOPPED:
+       case COMP_COMMAND_RING_STOPPED:
                xhci_warn(xhci, "Timeout while waiting for evaluate context command\n");
                ret = -ETIME;
                break;
@@ -3432,7 +3433,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
        ret = reset_device_cmd->status;
        switch (ret) {
        case COMP_COMMAND_ABORTED:
-       case COMP_STOPPED:
+       case COMP_COMMAND_RING_STOPPED:
                xhci_warn(xhci, "Timeout waiting for reset device command\n");
                ret = -ETIME;
                goto command_cleanup;
@@ -3817,7 +3818,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
         */
        switch (command->status) {
        case COMP_COMMAND_ABORTED:
-       case COMP_STOPPED:
+       case COMP_COMMAND_RING_STOPPED:
                xhci_warn(xhci, "Timeout while waiting for setup device command\n");
                ret = -ETIME;
                break;
index e9cae4d82af2ec80a1bfa321871aa75895dda170..15d4e64d3b65277df6e9e5ac79454a9320d9d108 100644 (file)
@@ -192,7 +192,7 @@ static int chaoskey_probe(struct usb_interface *interface,
 
        dev->in_ep = in_ep;
 
-       if (udev->descriptor.idVendor != ALEA_VENDOR_ID)
+       if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID)
                dev->reads_started = 1;
 
        dev->size = size;
index 77569531b78a56d45fb43ee255a0a22e6da2979d..83b05a287b0c58f2b0b29f91fcddd0f307510b88 100644 (file)
@@ -554,7 +554,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd,
                        info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);
 
                        /* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
-                       info.speed = le16_to_cpu(dev->udev->speed);
+                       info.speed = dev->udev->speed;
                        info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
                        info.report_size = dev->report_size;
 
index aa3c280fdf8d40662e375466dd3b2648ec037fe1..0782ac6f5edfaa0542dfe173bd6969c8bba77372 100644 (file)
@@ -926,6 +926,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
                 USB_MAJOR, dev->minor);
 
 exit:
+       kfree(get_version_reply);
        return retval;
 
 error:
index 3c6948af726aad38f9cf3a294ded3c7dfbac04ab..f019d80ca9e40451a8a3bbca0671b95935a7798f 100644 (file)
@@ -973,7 +973,7 @@ sisusbcon_set_origin(struct vc_data *c)
 
        mutex_unlock(&sisusb->lock);
 
-       return 1;
+       return true;
 }
 
 /* Interface routine */
index ac3a4952abb4b290b019ac59fbddd7004b50d949..dbe617a735d8400576e53a84e488ea4ff9fc8466 100644 (file)
@@ -2780,10 +2780,11 @@ int musb_host_setup(struct musb *musb, int power_budget)
        int ret;
        struct usb_hcd *hcd = musb->hcd;
 
-       MUSB_HST_MODE(musb);
-       musb->xceiv->otg->default_a = 1;
-       musb->xceiv->otg->state = OTG_STATE_A_IDLE;
-
+       if (musb->port_mode == MUSB_PORT_MODE_HOST) {
+               MUSB_HST_MODE(musb);
+               musb->xceiv->otg->default_a = 1;
+               musb->xceiv->otg->state = OTG_STATE_A_IDLE;
+       }
        otg_set_host(musb->xceiv->otg, &hcd->self);
        hcd->self.otg_port = 1;
        musb->xceiv->otg->host = &hcd->self;
index 8b43c4b99f045325fd5c7160ee28cca73f8738af..7870b37e0ea5c6b5a1767e9469193d791107071c 100644 (file)
@@ -219,6 +219,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        u32                             dma_remaining;
        int                             src_burst, dst_burst;
        u16                             csr;
+       u32                             psize;
        int                             ch;
        s8                              dmareq;
        s8                              sync_dev;
@@ -390,15 +391,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
        if (chdat->tx) {
                /* Send transfer_packet_sz packets at a time */
-               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-                       chdat->transfer_packet_sz);
+               psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+               psize &= ~0x7ff;
+               psize |= chdat->transfer_packet_sz;
+               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
                musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
                        TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
        } else {
                /* Receive transfer_packet_sz packets at a time */
-               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-                       chdat->transfer_packet_sz << 16);
+               psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+               psize &= ~(0x7ff << 16);
+               psize |= (chdat->transfer_packet_sz << 16);
+               musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
                musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
                        TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
index d38780fa87881a0ef3696e73e61527304271393c..aba74f817dc6594064241013b92e31138e587dce 100644 (file)
@@ -809,10 +809,10 @@ static const struct usb_device_id id_table_combined[] = {
        { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
        { USB_DEVICE(FTDI_VID, CYBER_CORTEX_AV_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
-       { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
-               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
-       { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
-               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID, 1) },
+       { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID, 1) },
+       { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_PID, 1) },
+       { USB_DEVICE_INTERFACE_NUMBER(OLIMEX_VID, OLIMEX_ARM_USB_TINY_H_PID, 1) },
        { USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
@@ -1527,9 +1527,9 @@ static int set_serial_info(struct tty_struct *tty,
                                        (new_serial.flags & ASYNC_FLAGS));
        priv->custom_divisor = new_serial.custom_divisor;
 
+check_and_exit:
        write_latency_timer(port);
 
-check_and_exit:
        if ((old_priv.flags & ASYNC_SPD_MASK) !=
             (priv->flags & ASYNC_SPD_MASK)) {
                if ((priv->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
index 71fb9e59db7125c845a9a1c23c4e33430a142a3e..4fcf1cecb6d721ad366666eec49774bcf9d00808 100644 (file)
 /* Olimex */
 #define OLIMEX_VID                     0x15BA
 #define OLIMEX_ARM_USB_OCD_PID         0x0003
+#define OLIMEX_ARM_USB_TINY_PID        0x0004
+#define OLIMEX_ARM_USB_TINY_H_PID      0x002a
 #define OLIMEX_ARM_USB_OCD_H_PID       0x002b
 
 /*
index 87798e625d6c827ed09b79a011eb46cdd770c864..6cefb9cb133d7bad8678e9b9400b077afc75474e 100644 (file)
@@ -2336,8 +2336,11 @@ static void change_port_settings(struct tty_struct *tty,
        if (!baud) {
                /* pick a default, any default... */
                baud = 9600;
-       } else
+       } else {
+               /* Avoid a zero divisor. */
+               baud = min(baud, 461550);
                tty_encode_baud_rate(tty, baud, baud);
+       }
 
        edge_port->baud_rate = baud;
        config->wBaudRate = (__u16)((461550L + baud/2) / baud);
index 73956d48a0c57bb5566fb0c1b47a581e438bb4a1..f9734a96d51681d689c5028e6777fec03c401d5a 100644 (file)
@@ -197,6 +197,7 @@ static u8 ir_xbof_change(u8 xbof)
 static int ir_startup(struct usb_serial *serial)
 {
        struct usb_irda_cs_descriptor *irda_desc;
+       int rates;
 
        irda_desc = irda_usb_find_class_desc(serial, 0);
        if (!irda_desc) {
@@ -205,18 +206,20 @@ static int ir_startup(struct usb_serial *serial)
                return -ENODEV;
        }
 
+       rates = le16_to_cpu(irda_desc->wBaudRate);
+
        dev_dbg(&serial->dev->dev,
                "%s - Baud rates supported:%s%s%s%s%s%s%s%s%s\n",
                __func__,
-               (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "",
-               (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : "");
+               (rates & USB_IRDA_BR_2400) ? " 2400" : "",
+               (rates & USB_IRDA_BR_9600) ? " 9600" : "",
+               (rates & USB_IRDA_BR_19200) ? " 19200" : "",
+               (rates & USB_IRDA_BR_38400) ? " 38400" : "",
+               (rates & USB_IRDA_BR_57600) ? " 57600" : "",
+               (rates & USB_IRDA_BR_115200) ? " 115200" : "",
+               (rates & USB_IRDA_BR_576000) ? " 576000" : "",
+               (rates & USB_IRDA_BR_1152000) ? " 1152000" : "",
+               (rates & USB_IRDA_BR_4000000) ? " 4000000" : "");
 
        switch (irda_desc->bmAdditionalBOFs) {
        case USB_IRDA_AB_48:
index edbc81f205c253f41f7afa2d3375ef7818e0ae86..70f346f1aa86f4a7c9eb880cd725cd0d2e6fb1b5 100644 (file)
@@ -189,7 +189,7 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
                return -ENOMEM;
 
        divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
-       put_unaligned_le32(cpu_to_le32(divisor), buf);
+       put_unaligned_le32(divisor, buf);
        rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
                                MCT_U232_SET_BAUD_RATE_REQUEST,
                                MCT_U232_SET_REQUEST_TYPE,
index af67a0de6b5d475d2be95952ddfb2354546a0fbb..3bf61acfc26b9cfdee5496feeb64bdbcfd58015c 100644 (file)
@@ -281,6 +281,7 @@ static void option_instat_callback(struct urb *urb);
 #define TELIT_PRODUCT_LE922_USBCFG0            0x1042
 #define TELIT_PRODUCT_LE922_USBCFG3            0x1043
 #define TELIT_PRODUCT_LE922_USBCFG5            0x1045
+#define TELIT_PRODUCT_ME910                    0x1100
 #define TELIT_PRODUCT_LE920                    0x1200
 #define TELIT_PRODUCT_LE910                    0x1201
 #define TELIT_PRODUCT_LE910_USBCFG4            0x1206
@@ -640,6 +641,11 @@ static const struct option_blacklist_info simcom_sim7100e_blacklist = {
        .reserved = BIT(5) | BIT(6),
 };
 
+static const struct option_blacklist_info telit_me910_blacklist = {
+       .sendsetup = BIT(0),
+       .reserved = BIT(1) | BIT(3),
+};
+
 static const struct option_blacklist_info telit_le910_blacklist = {
        .sendsetup = BIT(0),
        .reserved = BIT(1) | BIT(2),
@@ -1235,6 +1241,8 @@ static const struct usb_device_id option_ids[] = {
                .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
        { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
                .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
+               .driver_info = (kernel_ulong_t)&telit_me910_blacklist },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
                .driver_info = (kernel_ulong_t)&telit_le910_blacklist },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
index 38b3f0d8cd580f2366136003934d00a475b1d7f1..fd509ed6cf7065725c097ab1bc4eac84359be1f6 100644 (file)
@@ -162,6 +162,8 @@ static const struct usb_device_id id_table[] = {
        {DEVICE_SWI(0x1199, 0x9071)},   /* Sierra Wireless MC74xx */
        {DEVICE_SWI(0x1199, 0x9078)},   /* Sierra Wireless EM74xx */
        {DEVICE_SWI(0x1199, 0x9079)},   /* Sierra Wireless EM74xx */
+       {DEVICE_SWI(0x1199, 0x907a)},   /* Sierra Wireless EM74xx QDL */
+       {DEVICE_SWI(0x1199, 0x907b)},   /* Sierra Wireless EM74xx */
        {DEVICE_SWI(0x413c, 0x81a2)},   /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81a3)},   /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
        {DEVICE_SWI(0x413c, 0x81a4)},   /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
index 369f3c24815a1462f405f1a6bc3f2cbdd034e21b..44af719194b239f760c77919bf7cf5bad19ed9d7 100644 (file)
@@ -446,6 +446,10 @@ struct ms_lib_ctrl {
 #define SD_BLOCK_LEN  9
 
 struct ene_ub6250_info {
+
+       /* I/O bounce buffer */
+       u8              *bbuf;
+
        /* for 6250 code */
        struct SD_STATUS        SD_Status;
        struct MS_STATUS        MS_Status;
@@ -493,8 +497,11 @@ static int ene_load_bincode(struct us_data *us, unsigned char flag);
 
 static void ene_ub6250_info_destructor(void *extra)
 {
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) extra;
+
        if (!extra)
                return;
+       kfree(info->bbuf);
 }
 
 static int ene_send_scsi_cmd(struct us_data *us, u8 fDir, void *buf, int use_sg)
@@ -860,8 +867,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
                u8 PageNum, u32 *PageBuf, struct ms_lib_type_extdat *ExtraDat)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
        u32 bn = PhyBlockAddr * 0x20 + PageNum;
 
        result = ene_load_bincode(us, MS_RW_PATTERN);
@@ -901,7 +909,7 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
        bcb->CDB[2]     = (unsigned char)(PhyBlockAddr>>16);
        bcb->CDB[6]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
@@ -910,9 +918,9 @@ static int ms_read_readpage(struct us_data *us, u32 PhyBlockAddr,
        ExtraDat->status0  = 0x10;  /* Not yet,fireware support */
 
        ExtraDat->status1  = 0x00;  /* Not yet,fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
 
        return USB_STOR_TRANSPORT_GOOD;
 }
@@ -1332,8 +1340,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
                                u8 PageNum, struct ms_lib_type_extdat *ExtraDat)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
+       struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
        int result;
-       u8 ExtBuf[4];
 
        memset(bcb, 0, sizeof(struct bulk_cb_wrap));
        bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -1347,7 +1356,7 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
        bcb->CDB[2]     = (unsigned char)(PhyBlock>>16);
        bcb->CDB[6]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &ExtBuf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
@@ -1355,9 +1364,9 @@ static int ms_lib_read_extra(struct us_data *us, u32 PhyBlock,
        ExtraDat->intr     = 0x80;  /* Not yet, waiting for fireware support */
        ExtraDat->status0  = 0x10;  /* Not yet, waiting for fireware support */
        ExtraDat->status1  = 0x00;  /* Not yet, waiting for fireware support */
-       ExtraDat->ovrflg   = ExtBuf[0];
-       ExtraDat->mngflg   = ExtBuf[1];
-       ExtraDat->logadr   = memstick_logaddr(ExtBuf[2], ExtBuf[3]);
+       ExtraDat->ovrflg   = bbuf[0];
+       ExtraDat->mngflg   = bbuf[1];
+       ExtraDat->logadr   = memstick_logaddr(bbuf[2], bbuf[3]);
 
        return USB_STOR_TRANSPORT_GOOD;
 }
@@ -1556,9 +1565,9 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
        u16 PhyBlock, newblk, i;
        u16 LogStart, LogEnde;
        struct ms_lib_type_extdat extdat;
-       u8 buf[0x200];
        u32 count = 0, index = 0;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        for (PhyBlock = 0; PhyBlock < info->MS_Lib.NumberOfPhyBlock;) {
                ms_lib_phy_to_log_range(PhyBlock, &LogStart, &LogEnde);
@@ -1572,14 +1581,16 @@ static int ms_lib_scan_logicalblocknumber(struct us_data *us, u16 btBlk1st)
                        }
 
                        if (count == PhyBlock) {
-                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80, &buf);
+                               ms_lib_read_extrablock(us, PhyBlock, 0, 0x80,
+                                               bbuf);
                                count += 0x80;
                        }
                        index = (PhyBlock % 0x80) * 4;
 
-                       extdat.ovrflg = buf[index];
-                       extdat.mngflg = buf[index+1];
-                       extdat.logadr = memstick_logaddr(buf[index+2], buf[index+3]);
+                       extdat.ovrflg = bbuf[index];
+                       extdat.mngflg = bbuf[index+1];
+                       extdat.logadr = memstick_logaddr(bbuf[index+2],
+                                       bbuf[index+3]);
 
                        if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK) {
                                ms_lib_setacquired_errorblock(us, PhyBlock);
@@ -2062,9 +2073,9 @@ static int ene_ms_init(struct us_data *us)
 {
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        int result;
-       u8 buf[0x200];
        u16 MSP_BlockSize, MSP_UserAreaBlocks;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        printk(KERN_INFO "transport --- ENE_MSInit\n");
 
@@ -2083,13 +2094,13 @@ static int ene_ms_init(struct us_data *us)
        bcb->CDB[0]     = 0xF1;
        bcb->CDB[1]     = 0x01;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                printk(KERN_ERR "Execution MS Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
        /* the same part to test ENE */
-       info->MS_Status = *(struct MS_STATUS *)&buf[0];
+       info->MS_Status = *(struct MS_STATUS *) bbuf;
 
        if (info->MS_Status.Insert && info->MS_Status.Ready) {
                printk(KERN_INFO "Insert     = %x\n", info->MS_Status.Insert);
@@ -2098,15 +2109,15 @@ static int ene_ms_init(struct us_data *us)
                printk(KERN_INFO "IsMSPHG    = %x\n", info->MS_Status.IsMSPHG);
                printk(KERN_INFO "WtP= %x\n", info->MS_Status.WtP);
                if (info->MS_Status.IsMSPro) {
-                       MSP_BlockSize      = (buf[6] << 8) | buf[7];
-                       MSP_UserAreaBlocks = (buf[10] << 8) | buf[11];
+                       MSP_BlockSize      = (bbuf[6] << 8) | bbuf[7];
+                       MSP_UserAreaBlocks = (bbuf[10] << 8) | bbuf[11];
                        info->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks;
                } else {
                        ms_card_init(us); /* Card is MS (to ms.c)*/
                }
                usb_stor_dbg(us, "MS Init Code OK !!\n");
        } else {
-               usb_stor_dbg(us, "MS Card Not Ready --- %x\n", buf[0]);
+               usb_stor_dbg(us, "MS Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
 
@@ -2116,9 +2127,9 @@ static int ene_ms_init(struct us_data *us)
 static int ene_sd_init(struct us_data *us)
 {
        int result;
-       u8  buf[0x200];
        struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra;
+       u8 *bbuf = info->bbuf;
 
        usb_stor_dbg(us, "transport --- ENE_SDInit\n");
        /* SD Init Part-1 */
@@ -2152,17 +2163,17 @@ static int ene_sd_init(struct us_data *us)
        bcb->Flags              = US_BULK_FLAG_IN;
        bcb->CDB[0]             = 0xF1;
 
-       result = ene_send_scsi_cmd(us, FDIR_READ, &buf, 0);
+       result = ene_send_scsi_cmd(us, FDIR_READ, bbuf, 0);
        if (result != USB_STOR_XFER_GOOD) {
                usb_stor_dbg(us, "Execution SD Init Code Fail !!\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
 
-       info->SD_Status =  *(struct SD_STATUS *)&buf[0];
+       info->SD_Status =  *(struct SD_STATUS *) bbuf;
        if (info->SD_Status.Insert && info->SD_Status.Ready) {
                struct SD_STATUS *s = &info->SD_Status;
 
-               ene_get_card_status(us, (unsigned char *)&buf);
+               ene_get_card_status(us, bbuf);
                usb_stor_dbg(us, "Insert     = %x\n", s->Insert);
                usb_stor_dbg(us, "Ready      = %x\n", s->Ready);
                usb_stor_dbg(us, "IsMMC      = %x\n", s->IsMMC);
@@ -2170,7 +2181,7 @@ static int ene_sd_init(struct us_data *us)
                usb_stor_dbg(us, "HiSpeed    = %x\n", s->HiSpeed);
                usb_stor_dbg(us, "WtP        = %x\n", s->WtP);
        } else {
-               usb_stor_dbg(us, "SD Card Not Ready --- %x\n", buf[0]);
+               usb_stor_dbg(us, "SD Card Not Ready --- %x\n", bbuf[0]);
                return USB_STOR_TRANSPORT_ERROR;
        }
        return USB_STOR_TRANSPORT_GOOD;
@@ -2180,13 +2191,15 @@ static int ene_sd_init(struct us_data *us)
 static int ene_init(struct us_data *us)
 {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct ene_ub6250_info *info = (struct ene_ub6250_info *)(us->extra);
+       u8 *bbuf = info->bbuf;
 
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, bbuf);
        if (result != USB_STOR_XFER_GOOD)
                return USB_STOR_TRANSPORT_ERROR;
 
+       misc_reg03 = bbuf[0];
        if (misc_reg03 & 0x01) {
                if (!info->SD_Status.Ready) {
                        result = ene_sd_init(us);
@@ -2303,8 +2316,9 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
 {
        int result;
-       u8  misc_reg03 = 0;
+       u8  misc_reg03;
        struct us_data *us;
+       struct ene_ub6250_info *info;
 
        result = usb_stor_probe1(&us, intf, id,
                   (id - ene_ub6250_usb_ids) + ene_ub6250_unusual_dev_list,
@@ -2313,11 +2327,16 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                return result;
 
        /* FIXME: where should the code alloc extra buf ? */
-       if (!us->extra) {
-               us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
-               if (!us->extra)
-                       return -ENOMEM;
-               us->extra_destructor = ene_ub6250_info_destructor;
+       us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL);
+       if (!us->extra)
+               return -ENOMEM;
+       us->extra_destructor = ene_ub6250_info_destructor;
+
+       info = (struct ene_ub6250_info *)(us->extra);
+       info->bbuf = kmalloc(512, GFP_KERNEL);
+       if (!info->bbuf) {
+               kfree(us->extra);
+               return -ENOMEM;
        }
 
        us->transport_name = "ene_ub6250";
@@ -2329,12 +2348,13 @@ static int ene_ub6250_probe(struct usb_interface *intf,
                return result;
 
        /* probe card type */
-       result = ene_get_card_type(us, REG_CARD_STATUS, &misc_reg03);
+       result = ene_get_card_type(us, REG_CARD_STATUS, info->bbuf);
        if (result != USB_STOR_XFER_GOOD) {
                usb_stor_disconnect(intf);
                return USB_STOR_TRANSPORT_ERROR;
        }
 
+       misc_reg03 = info->bbuf[0];
        if (!(misc_reg03 & 0x01)) {
                pr_info("ums_eneub6250: This driver only supports SD/MS cards. "
                        "It does not support SM cards.\n");
index 5d8b2c261940d9a7785bc64a505f2959f57cb395..0585078638db7ebcf72a40fc9f9ecdf3ea362512 100644 (file)
@@ -235,14 +235,19 @@ done:
 
 static inline void hub_descriptor(struct usb_hub_descriptor *desc)
 {
+       int width;
+
        memset(desc, 0, sizeof(*desc));
        desc->bDescriptorType = USB_DT_HUB;
-       desc->bDescLength = 9;
        desc->wHubCharacteristics = cpu_to_le16(
                HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_COMMON_OCPM);
+
        desc->bNbrPorts = VHCI_HC_PORTS;
-       desc->u.hs.DeviceRemovable[0] = 0xff;
-       desc->u.hs.DeviceRemovable[1] = 0xff;
+       BUILD_BUG_ON(VHCI_HC_PORTS > USB_MAXCHILDREN);
+       width = desc->bNbrPorts / 8 + 1;
+       desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * width;
+       memset(&desc->u.hs.DeviceRemovable[0], 0, width);
+       memset(&desc->u.hs.DeviceRemovable[width], 0xff, width);
 }
 
 static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
index 6345e85822a42457f11c607effb3fbb66ce8c89f..a50cf45e530f7f0dcc76c111da56d919b9f1f1bf 100644 (file)
@@ -341,6 +341,7 @@ error_submit_ep1:
 static
 int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
 {
+       struct usb_device *udev = interface_to_usbdev(iface);
        struct i1480_usb *i1480_usb;
        struct i1480 *i1480;
        struct device *dev = &iface->dev;
@@ -352,8 +353,8 @@ int i1480_usb_probe(struct usb_interface *iface, const struct usb_device_id *id)
                        iface->cur_altsetting->desc.bInterfaceNumber);
                goto error;
        }
-       if (iface->num_altsetting > 1
-           && interface_to_usbdev(iface)->descriptor.idProduct == 0xbabe) {
+       if (iface->num_altsetting > 1 &&
+                       le16_to_cpu(udev->descriptor.idProduct) == 0xbabe) {
                /* Need altsetting #1 [HW QUIRK] or EP1 won't work */
                result = usb_set_interface(interface_to_usbdev(iface), 0, 1);
                if (result < 0)
index 52a70ee6014fa866762042f78b87f3a4c7c7e794..8b9049dac0948db6cc0fca2f25c9f4e5f5cae6bd 100644 (file)
@@ -452,7 +452,7 @@ config DAVINCI_WATCHDOG
 
 config ORION_WATCHDOG
        tristate "Orion watchdog"
-       depends on ARCH_ORION5X || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU || COMPILE_TEST
+       depends on ARCH_ORION5X || ARCH_DOVE || MACH_DOVE || ARCH_MVEBU || (COMPILE_TEST && !ARCH_EBSA110)
        depends on ARM
        select WATCHDOG_CORE
        help
index 6fce17d5b9f1a27f94e711d0e69d9844c920a91d..a5775dfd8d5fc226e31ca59abb172f504f7efcda 100644 (file)
@@ -304,6 +304,8 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
        if (!wdt)
                return -ENOMEM;
 
+       spin_lock_init(&wdt->lock);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        wdt->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(wdt->base))
@@ -316,7 +318,6 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
                return ret;
        }
 
-       spin_lock_init(&wdt->lock);
        platform_set_drvdata(pdev, wdt);
        watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
        bcm_kona_wdt_wdd.parent = &pdev->dev;
index 8d61e8bfe60b1a418eab489e966652840dedccff..86e0b5d2e7616690007792833e96cc9086ee0144 100644 (file)
@@ -49,7 +49,7 @@
 /* Counter maximum value */
 #define CDNS_WDT_COUNTER_MAX 0xFFF
 
-static int wdt_timeout = CDNS_WDT_DEFAULT_TIMEOUT;
+static int wdt_timeout;
 static int nowayout = WATCHDOG_NOWAYOUT;
 
 module_param(wdt_timeout, int, 0);
index 347f0389b0899d4183021254203e0a0938600267..c4f65873bfa453b1385d2a1371ba10c741df2be9 100644 (file)
@@ -306,16 +306,15 @@ static int iTCO_wdt_ping(struct watchdog_device *wd_dev)
 
        iTCO_vendor_pre_keepalive(p->smi_res, wd_dev->timeout);
 
+       /* Reset the timeout status bit so that the timer
+        * needs to count down twice again before rebooting */
+       outw(0x0008, TCO1_STS(p));      /* write 1 to clear bit */
+
        /* Reload the timer by writing to the TCO Timer Counter register */
-       if (p->iTCO_version >= 2) {
+       if (p->iTCO_version >= 2)
                outw(0x01, TCO_RLD(p));
-       } else if (p->iTCO_version == 1) {
-               /* Reset the timeout status bit so that the timer
-                * needs to count down twice again before rebooting */
-               outw(0x0008, TCO1_STS(p));      /* write 1 to clear bit */
-
+       else if (p->iTCO_version == 1)
                outb(0x01, TCO_RLD(p));
-       }
 
        spin_unlock(&p->io_lock);
        return 0;
@@ -328,11 +327,8 @@ static int iTCO_wdt_set_timeout(struct watchdog_device *wd_dev, unsigned int t)
        unsigned char val8;
        unsigned int tmrval;
 
-       tmrval = seconds_to_ticks(p, t);
-
-       /* For TCO v1 the timer counts down twice before rebooting */
-       if (p->iTCO_version == 1)
-               tmrval /= 2;
+       /* The timer counts down twice before rebooting */
+       tmrval = seconds_to_ticks(p, t) / 2;
 
        /* from the specs: */
        /* "Values of 0h-3h are ignored and should not be attempted" */
@@ -385,6 +381,8 @@ static unsigned int iTCO_wdt_get_timeleft(struct watchdog_device *wd_dev)
                spin_lock(&p->io_lock);
                val16 = inw(TCO_RLD(p));
                val16 &= 0x3ff;
+               if (!(inw(TCO1_STS(p)) & 0x0008))
+                       val16 += (inw(TCOv2_TMR(p)) & 0x3ff);
                spin_unlock(&p->io_lock);
 
                time_left = ticks_to_seconds(p, val16);
index 99ebf6ea3de648d881de4ef1f609d1f4d29f5ca0..5615f40139246a19de1be39df6f6ca60b7a705b9 100644 (file)
@@ -630,6 +630,9 @@ static int usb_pcwd_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
+       if (iface_desc->desc.bNumEndpoints < 1)
+               return -ENODEV;
+
        /* check out the endpoint: it has to be Interrupt & IN */
        endpoint = &iface_desc->endpoint[0].desc;
 
index f709962018ac260107dd2c419c1fbcdfafd4599b..362fd229786df6cea1600108a9060b89b800f475 100644 (file)
@@ -6,6 +6,7 @@
  * Licensed under GPLv2.
  */
 
+#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -29,6 +30,7 @@ struct sama5d4_wdt {
        struct watchdog_device  wdd;
        void __iomem            *reg_base;
        u32                     mr;
+       unsigned long           last_ping;
 };
 
 static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
@@ -44,11 +46,34 @@ MODULE_PARM_DESC(nowayout,
        "Watchdog cannot be stopped once started (default="
        __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
+#define wdt_enabled (!(wdt->mr & AT91_WDT_WDDIS))
+
 #define wdt_read(wdt, field) \
        readl_relaxed((wdt)->reg_base + (field))
 
-#define wdt_write(wtd, field, val) \
-       writel_relaxed((val), (wdt)->reg_base + (field))
+/* 4 slow clock periods is 4/32768 = 122.07µs*/
+#define WDT_DELAY      usecs_to_jiffies(123)
+
+static void wdt_write(struct sama5d4_wdt *wdt, u32 field, u32 val)
+{
+       /*
+        * WDT_CR and WDT_MR must not be modified within three slow clock
+        * periods following a restart of the watchdog performed by a write
+        * access in WDT_CR.
+        */
+       while (time_before(jiffies, wdt->last_ping + WDT_DELAY))
+               usleep_range(30, 125);
+       writel_relaxed(val, wdt->reg_base + field);
+       wdt->last_ping = jiffies;
+}
+
+static void wdt_write_nosleep(struct sama5d4_wdt *wdt, u32 field, u32 val)
+{
+       if (time_before(jiffies, wdt->last_ping + WDT_DELAY))
+               udelay(123);
+       writel_relaxed(val, wdt->reg_base + field);
+       wdt->last_ping = jiffies;
+}
 
 static int sama5d4_wdt_start(struct watchdog_device *wdd)
 {
@@ -89,7 +114,16 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
        wdt->mr &= ~AT91_WDT_WDD;
        wdt->mr |= AT91_WDT_SET_WDV(value);
        wdt->mr |= AT91_WDT_SET_WDD(value);
-       wdt_write(wdt, AT91_WDT_MR, wdt->mr);
+
+       /*
+        * WDDIS has to be 0 when updating WDD/WDV. The datasheet states: When
+        * setting the WDDIS bit, and while it is set, the fields WDV and WDD
+        * must not be modified.
+        * If the watchdog is enabled, then the timeout can be updated. Else,
+        * wait that the user enables it.
+        */
+       if (wdt_enabled)
+               wdt_write(wdt, AT91_WDT_MR, wdt->mr & ~AT91_WDT_WDDIS);
 
        wdd->timeout = timeout;
 
@@ -145,23 +179,21 @@ static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
 
 static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
 {
-       struct watchdog_device *wdd = &wdt->wdd;
-       u32 value = WDT_SEC2TICKS(wdd->timeout);
        u32 reg;
-
        /*
-        * Because the fields WDV and WDD must not be modified when the WDDIS
-        * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+        * When booting and resuming, the bootloader may have changed the
+        * watchdog configuration.
+        * If the watchdog is already running, we can safely update it.
+        * Else, we have to disable it properly.
         */
-       reg = wdt_read(wdt, AT91_WDT_MR);
-       reg &= ~AT91_WDT_WDDIS;
-       wdt_write(wdt, AT91_WDT_MR, reg);
-
-       wdt->mr |= AT91_WDT_SET_WDD(value);
-       wdt->mr |= AT91_WDT_SET_WDV(value);
-
-       wdt_write(wdt, AT91_WDT_MR, wdt->mr);
-
+       if (wdt_enabled) {
+               wdt_write_nosleep(wdt, AT91_WDT_MR, wdt->mr);
+       } else {
+               reg = wdt_read(wdt, AT91_WDT_MR);
+               if (!(reg & AT91_WDT_WDDIS))
+                       wdt_write_nosleep(wdt, AT91_WDT_MR,
+                                         reg | AT91_WDT_WDDIS);
+       }
        return 0;
 }
 
@@ -172,6 +204,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
        struct resource *res;
        void __iomem *regs;
        u32 irq = 0;
+       u32 timeout;
        int ret;
 
        wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -184,6 +217,7 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
        wdd->ops = &sama5d4_wdt_ops;
        wdd->min_timeout = MIN_WDT_TIMEOUT;
        wdd->max_timeout = MAX_WDT_TIMEOUT;
+       wdt->last_ping = jiffies;
 
        watchdog_set_drvdata(wdd, wdt);
 
@@ -221,6 +255,11 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
                return ret;
        }
 
+       timeout = WDT_SEC2TICKS(wdd->timeout);
+
+       wdt->mr |= AT91_WDT_SET_WDD(timeout);
+       wdt->mr |= AT91_WDT_SET_WDV(timeout);
+
        ret = sama5d4_wdt_init(wdt);
        if (ret)
                return ret;
@@ -263,9 +302,7 @@ static int sama5d4_wdt_resume(struct device *dev)
 {
        struct sama5d4_wdt *wdt = dev_get_drvdata(dev);
 
-       wdt_write(wdt, AT91_WDT_MR, wdt->mr & ~AT91_WDT_WDDIS);
-       if (wdt->mr & AT91_WDT_WDDIS)
-               wdt_write(wdt, AT91_WDT_MR, wdt->mr);
+       sama5d4_wdt_init(wdt);
 
        return 0;
 }
index 48b2c058b00910ffee5a313812b5cb4d0ee135c5..bc7addc2dc06d0f9ca4bfa09abdbedfb4252090f 100644 (file)
@@ -332,7 +332,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id)
                pr_crit("Would Reboot\n");
 #else
                pr_crit("Initiating system reboot\n");
-               emergency_restart(NULL);
+               emergency_restart();
 #endif
 #else
                pr_crit("Reset in 5ms\n");
index e290d5a13a6d5fa621f650ef03f3b8d7f00f7bb5..c98252733c3069dc5528691cecdee279c8f35c5a 100644 (file)
@@ -211,10 +211,8 @@ static int zx2967_wdt_probe(struct platform_device *pdev)
 
        base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        wdt->reg_base = devm_ioremap_resource(dev, base);
-       if (IS_ERR(wdt->reg_base)) {
-               dev_err(dev, "ioremap failed\n");
+       if (IS_ERR(wdt->reg_base))
                return PTR_ERR(wdt->reg_base);
-       }
 
        zx2967_wdt_reset_sysctrl(dev);
 
index 15bac390dff945d7fa5d785f666b2b0291fb9f65..b98436f5c7c74f9e773db0485bb9e80fcb43be99 100644 (file)
@@ -1135,20 +1135,19 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
        u32 acllen = 0;
        int rc = 0;
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
-       struct cifs_tcon *tcon;
+       struct smb_version_operations *ops;
 
        cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
 
        if (IS_ERR(tlink))
                return PTR_ERR(tlink);
-       tcon = tlink_tcon(tlink);
 
-       if (pfid && (tcon->ses->server->ops->get_acl_by_fid))
-               pntsd = tcon->ses->server->ops->get_acl_by_fid(cifs_sb, pfid,
-                                                         &acllen);
-       else if (tcon->ses->server->ops->get_acl)
-               pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path,
-                                                       &acllen);
+       ops = tlink_tcon(tlink)->ses->server->ops;
+
+       if (pfid && (ops->get_acl_by_fid))
+               pntsd = ops->get_acl_by_fid(cifs_sb, pfid, &acllen);
+       else if (ops->get_acl)
+               pntsd = ops->get_acl(cifs_sb, inode, path, &acllen);
        else {
                cifs_put_tlink(tlink);
                return -EOPNOTSUPP;
@@ -1181,23 +1180,23 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
        struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
        struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
-       struct cifs_tcon *tcon;
+       struct smb_version_operations *ops;
 
        if (IS_ERR(tlink))
                return PTR_ERR(tlink);
-       tcon = tlink_tcon(tlink);
+
+       ops = tlink_tcon(tlink)->ses->server->ops;
 
        cifs_dbg(NOISY, "set ACL from mode for %s\n", path);
 
        /* Get the security descriptor */
 
-       if (tcon->ses->server->ops->get_acl == NULL) {
+       if (ops->get_acl == NULL) {
                cifs_put_tlink(tlink);
                return -EOPNOTSUPP;
        }
 
-       pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path,
-                                               &secdesclen);
+       pntsd = ops->get_acl(cifs_sb, inode, path, &secdesclen);
        if (IS_ERR(pntsd)) {
                rc = PTR_ERR(pntsd);
                cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc);
@@ -1224,13 +1223,12 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
 
        cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
 
-       if (tcon->ses->server->ops->set_acl == NULL)
+       if (ops->set_acl == NULL)
                rc = -EOPNOTSUPP;
 
        if (!rc) {
                /* Set the security descriptor */
-               rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode,
-                                                    path, aclflag);
+               rc = ops->set_acl(pnntsd, secdesclen, inode, path, aclflag);
                cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
        }
        cifs_put_tlink(tlink);
index 8be55be70faf6c278de7b7c623501385bf21acaf..bcc7d9acad64b3a59b9c966956accb2c51d9ac13 100644 (file)
@@ -418,7 +418,7 @@ struct smb_version_operations {
        int (*validate_negotiate)(const unsigned int, struct cifs_tcon *);
        ssize_t (*query_all_EAs)(const unsigned int, struct cifs_tcon *,
                        const unsigned char *, const unsigned char *, char *,
-                       size_t, const struct nls_table *, int);
+                       size_t, struct cifs_sb_info *);
        int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *,
                        const char *, const void *, const __u16,
                        const struct nls_table *, int);
index e49958c3f8bbded4265b71e47a87d736a34676da..6eb3147132e30c2225b610b01281111bb896c617 100644 (file)
@@ -480,8 +480,7 @@ extern int CIFSSMBCopy(unsigned int xid,
 extern ssize_t CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
                        const unsigned char *searchName,
                        const unsigned char *ea_name, char *EAData,
-                       size_t bufsize, const struct nls_table *nls_codepage,
-                       int remap_special_chars);
+                       size_t bufsize, struct cifs_sb_info *cifs_sb);
 extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
                const char *fileName, const char *ea_name,
                const void *ea_value, const __u16 ea_value_len,
index 4c01b3f9abf02efb70648e030998220bab13bd55..fbb0d4cbda413e5349ab97c8fdfe65435efdc6ed 100644 (file)
@@ -697,9 +697,7 @@ cifs_echo_callback(struct mid_q_entry *mid)
 {
        struct TCP_Server_Info *server = mid->callback_data;
 
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(server, 1, CIFS_ECHO_OP);
 }
 
@@ -1599,9 +1597,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
        }
 
        queue_work(cifsiod_wq, &rdata->work);
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(server, 1, 0);
 }
 
@@ -2058,7 +2054,6 @@ cifs_writev_callback(struct mid_q_entry *mid)
 {
        struct cifs_writedata *wdata = mid->callback_data;
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
-       struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int written;
        WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
 
@@ -2095,9 +2090,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
        }
 
        queue_work(cifsiod_wq, &wdata->work);
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(tcon->ses->server, 1, 0);
 }
 
@@ -6076,11 +6069,13 @@ ssize_t
 CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
                const unsigned char *searchName, const unsigned char *ea_name,
                char *EAData, size_t buf_size,
-               const struct nls_table *nls_codepage, int remap)
+               struct cifs_sb_info *cifs_sb)
 {
                /* BB assumes one setup word */
        TRANSACTION2_QPI_REQ *pSMB = NULL;
        TRANSACTION2_QPI_RSP *pSMBr = NULL;
+       int remap = cifs_remap(cifs_sb);
+       struct nls_table *nls_codepage = cifs_sb->local_nls;
        int rc = 0;
        int bytes_returned;
        int list_len;
index 6ef78ad838e6e3e8b4cf24e72de24fcba8e4313c..0fd081bd2a2f5d3fb4ed18fdcb7a1371cf9f5627 100644 (file)
@@ -582,7 +582,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        int rc = 0;
 
-       down_read(&cinode->lock_sem);
+       down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);
        if (cinode->can_cache_brlcks) {
                /* can cache locks - no need to relock */
                up_read(&cinode->lock_sem);
index c3b2fa0b2ec8a6ceed83a74b65bd60cc1e1a7cee..4d1fcd76d022f6848c16294411d5a937e053e27a 100644 (file)
@@ -563,8 +563,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
 
        rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path,
                        "SETFILEBITS", ea_value, 4 /* size of buf */,
-                       cifs_sb->local_nls,
-                       cifs_remap(cifs_sb));
+                       cifs_sb);
        cifs_put_tlink(tlink);
        if (rc < 0)
                return (int)rc;
index 48ff7703b91912c79b8412539919c3ce6fe76ac6..e4afdaae743f28cf2d1396faed88e7465f875d48 100644 (file)
@@ -1240,15 +1240,19 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
                goto tcon_exit;
        }
 
-       if (rsp->ShareType & SMB2_SHARE_TYPE_DISK)
+       switch (rsp->ShareType) {
+       case SMB2_SHARE_TYPE_DISK:
                cifs_dbg(FYI, "connection to disk share\n");
-       else if (rsp->ShareType & SMB2_SHARE_TYPE_PIPE) {
+               break;
+       case SMB2_SHARE_TYPE_PIPE:
                tcon->ipc = true;
                cifs_dbg(FYI, "connection to pipe share\n");
-       } else if (rsp->ShareType & SMB2_SHARE_TYPE_PRINT) {
-               tcon->print = true;
+               break;
+       case SMB2_SHARE_TYPE_PRINT:
+               tcon->ipc = true;
                cifs_dbg(FYI, "connection to printer\n");
-       } else {
+               break;
+       default:
                cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
                rc = -EOPNOTSUPP;
                goto tcon_error_exit;
@@ -2173,9 +2177,7 @@ smb2_echo_callback(struct mid_q_entry *mid)
        if (mid->mid_state == MID_RESPONSE_RECEIVED)
                credits_received = le16_to_cpu(rsp->hdr.sync_hdr.CreditRequest);
 
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(server, credits_received, CIFS_ECHO_OP);
 }
 
@@ -2433,9 +2435,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
                cifs_stats_fail_inc(tcon, SMB2_READ_HE);
 
        queue_work(cifsiod_wq, &rdata->work);
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(server, credits_received, 0);
 }
 
@@ -2594,7 +2594,6 @@ smb2_writev_callback(struct mid_q_entry *mid)
 {
        struct cifs_writedata *wdata = mid->callback_data;
        struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
-       struct TCP_Server_Info *server = tcon->ses->server;
        unsigned int written;
        struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
        unsigned int credits_received = 1;
@@ -2634,9 +2633,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
                cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
 
        queue_work(cifsiod_wq, &wdata->work);
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        add_credits(tcon->ses->server, credits_received, 0);
 }
 
index 4d64b5b8fc9c6fae67f7f3e0ec74284548ff7c32..47a125ece11ea0d3e2daa0814c8cab28b4643bb1 100644 (file)
@@ -94,7 +94,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
        now = jiffies;
        /* commands taking longer than one second are indications that
           something is wrong, unless it is quite a slow link or server */
-       if ((now - midEntry->when_alloc) > HZ) {
+       if (time_after(now, midEntry->when_alloc + HZ)) {
                if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) {
                        pr_debug(" CIFS slow rsp: cmd %d mid %llu",
                               midEntry->command, midEntry->mid);
@@ -613,9 +613,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
        }
        spin_unlock(&GlobalMid_Lock);
 
-       mutex_lock(&server->srv_mutex);
        DeleteMidQEntry(mid);
-       mutex_unlock(&server->srv_mutex);
        return rc;
 }
 
index 20af5187ba63cc14150185952a3f7cdf9526556d..3cb5c9e2d4e78f641549818fbbad7681b193854d 100644 (file)
@@ -235,8 +235,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler,
 
                if (pTcon->ses->server->ops->query_all_EAs)
                        rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
-                               full_path, name, value, size,
-                               cifs_sb->local_nls, cifs_remap(cifs_sb));
+                               full_path, name, value, size, cifs_sb);
                break;
 
        case XATTR_CIFS_ACL: {
@@ -336,8 +335,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
 
        if (pTcon->ses->server->ops->query_all_EAs)
                rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
-                               full_path, NULL, data, buf_size,
-                               cifs_sb->local_nls, cifs_remap(cifs_sb));
+                               full_path, NULL, data, buf_size, cifs_sb);
 list_ea_exit:
        kfree(full_path);
        free_xid(xid);
index 26d77f9f8c12e69f48bc6cc1c4f47bb6fab27ebd..2dcbd56988843ccdfb017c9b14ca8f5b05a31b62 100644 (file)
@@ -817,7 +817,7 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
        iomap->bdev = bdev;
        iomap->offset = (u64)first_block << blkbits;
        if (blk_queue_dax(bdev->bd_queue))
-               iomap->dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+               iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
        else
                iomap->dax_dev = NULL;
 
@@ -841,7 +841,7 @@ static int
 ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length,
                ssize_t written, unsigned flags, struct iomap *iomap)
 {
-       put_dax(iomap->dax_dev);
+       fs_put_dax(iomap->dax_dev);
        if (iomap->type == IOMAP_MAPPED &&
            written < length &&
            (flags & IOMAP_WRITE))
index 5834c4d76be80969125a9c2d56309e990ba07e84..1bd0bfa547f6deee46d8dfe039625ed1736d14ed 100644 (file)
@@ -3412,7 +3412,7 @@ retry:
        bdev = inode->i_sb->s_bdev;
        iomap->bdev = bdev;
        if (blk_queue_dax(bdev->bd_queue))
-               iomap->dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+               iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
        else
                iomap->dax_dev = NULL;
        iomap->offset = first_block << blkbits;
@@ -3447,7 +3447,7 @@ static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
        int blkbits = inode->i_blkbits;
        bool truncate = false;
 
-       put_dax(iomap->dax_dev);
+       fs_put_dax(iomap->dax_dev);
        if (!(flags & IOMAP_WRITE) || (flags & IOMAP_FAULT))
                return 0;
 
index 5a1b58f8fef4d2437842b73d4c1c12b2e87a32c9..65c88379a3a14311cca68b8750d6bb0b9f107444 100644 (file)
@@ -975,8 +975,15 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
        int err;
        char *suffix = "";
 
-       if (sb->s_bdev)
+       if (sb->s_bdev) {
                suffix = "-fuseblk";
+               /*
+                * sb->s_bdi points to blkdev's bdi however we want to redirect
+                * it to our private bdi...
+                */
+               bdi_put(sb->s_bdi);
+               sb->s_bdi = &noop_backing_dev_info;
+       }
        err = super_setup_bdi_name(sb, "%u:%u%s", MAJOR(fc->dev),
                                   MINOR(fc->dev), suffix);
        if (err)
index a63f61c256bdc54f0a8ee6088702dbd5e91ee9aa..94e5bdf7304cff79c9ad7784013520776e3086f8 100644 (file)
@@ -1068,7 +1068,7 @@ xfs_file_iomap_begin(
        /* optionally associate a dax device with the iomap bdev */
        bdev = iomap->bdev;
        if (blk_queue_dax(bdev->bd_queue))
-               iomap->dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+               iomap->dax_dev = fs_dax_get_by_host(bdev->bd_disk->disk_name);
        else
                iomap->dax_dev = NULL;
 
@@ -1149,7 +1149,7 @@ xfs_file_iomap_end(
        unsigned                flags,
        struct iomap            *iomap)
 {
-       put_dax(iomap->dax_dev);
+       fs_put_dax(iomap->dax_dev);
        if ((flags & IOMAP_WRITE) && iomap->type == IOMAP_DELALLOC)
                return xfs_file_iomap_end_delalloc(XFS_I(inode), offset,
                                length, written, iomap);
index 97b8d3728b3103f1b54f711f15d06fa84691e372..ef718586321ce0dea03aabe8b114beca9cb71a74 100644 (file)
@@ -195,7 +195,10 @@ struct vgic_dist {
                /* either a GICv2 CPU interface */
                gpa_t                   vgic_cpu_base;
                /* or a number of GICv3 redistributor regions */
-               gpa_t                   vgic_redist_base;
+               struct {
+                       gpa_t           vgic_redist_base;
+                       gpa_t           vgic_redist_free_offset;
+               };
        };
 
        /* distributor enabled */
index 5efb4db44e1ef3223d984296ccf1ca0737224d10..d5093b52b4855f5ec0fbd6d29df265da80945a68 100644 (file)
@@ -40,6 +40,9 @@ struct bpf_reg_state {
         */
        s64 min_value;
        u64 max_value;
+       u32 min_align;
+       u32 aux_off;
+       u32 aux_off_align;
 };
 
 enum bpf_stack_slot_type {
@@ -87,6 +90,7 @@ struct bpf_verifier_env {
        struct bpf_prog *prog;          /* eBPF program being verified */
        struct bpf_verifier_stack_elem *head; /* stack of verifier states to be processed */
        int stack_size;                 /* number of states to be processed */
+       bool strict_alignment;          /* perform strict pointer alignment checks */
        struct bpf_verifier_state cur_state; /* current verifier state */
        struct bpf_verifier_state_list **explored_states; /* search pruning optimization */
        const struct bpf_ext_analyzer_ops *analyzer_ops; /* external analyzer ops */
index 00ebac854bb79f16ed5b04d74c6dafa641de0bb7..5ec1f6c47716d6fe7c750456cef81cc0e321b1bc 100644 (file)
@@ -18,6 +18,20 @@ struct dax_operations {
                        void **, pfn_t *);
 };
 
+#if IS_ENABLED(CONFIG_DAX)
+struct dax_device *dax_get_by_host(const char *host);
+void put_dax(struct dax_device *dax_dev);
+#else
+static inline struct dax_device *dax_get_by_host(const char *host)
+{
+       return NULL;
+}
+
+static inline void put_dax(struct dax_device *dax_dev)
+{
+}
+#endif
+
 int bdev_dax_pgoff(struct block_device *, sector_t, size_t, pgoff_t *pgoff);
 #if IS_ENABLED(CONFIG_FS_DAX)
 int __bdev_dax_supported(struct super_block *sb, int blocksize);
@@ -25,23 +39,29 @@ static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
 {
        return __bdev_dax_supported(sb, blocksize);
 }
+
+static inline struct dax_device *fs_dax_get_by_host(const char *host)
+{
+       return dax_get_by_host(host);
+}
+
+static inline void fs_put_dax(struct dax_device *dax_dev)
+{
+       put_dax(dax_dev);
+}
+
 #else
 static inline int bdev_dax_supported(struct super_block *sb, int blocksize)
 {
        return -EOPNOTSUPP;
 }
-#endif
 
-#if IS_ENABLED(CONFIG_DAX)
-struct dax_device *dax_get_by_host(const char *host);
-void put_dax(struct dax_device *dax_dev);
-#else
-static inline struct dax_device *dax_get_by_host(const char *host)
+static inline struct dax_device *fs_dax_get_by_host(const char *host)
 {
        return NULL;
 }
 
-static inline void put_dax(struct dax_device *dax_dev)
+static inline void fs_put_dax(struct dax_device *dax_dev)
 {
 }
 #endif
index 30f90c1a0aaf923d2227ae5ba5323ea5da728005..541df0b5b81530741586d6eaf382e9d1a425ac06 100644 (file)
@@ -349,6 +349,9 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table,
                                             int write, void __user *buffer,
                                             size_t *length, loff_t *ppos);
 #endif
+extern void wait_for_kprobe_optimizer(void);
+#else
+static inline void wait_for_kprobe_optimizer(void) { }
 #endif /* CONFIG_OPTPROBES */
 #ifdef CONFIG_KPROBES_ON_FTRACE
 extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
index 1b166d2e19c57829279faa20a88796fabb5d3f5e..b25e7baa273e8d9db99fb1e2f33e3086ea875e89 100644 (file)
@@ -109,7 +109,6 @@ struct mlx5_flow_table_attr {
        int max_fte;
        u32 level;
        u32 flags;
-       u32 underlay_qpn;
 };
 
 struct mlx5_flow_table *
@@ -167,4 +166,7 @@ struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);
 void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
 void mlx5_fc_query_cached(struct mlx5_fc *counter,
                          u64 *bytes, u64 *packets, u64 *lastuse);
+int mlx5_fs_add_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn);
+int mlx5_fs_remove_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn);
+
 #endif
index 9c23bd2efb56393e7c616d42d427101c3f5f51d2..3f39d27decf4d72e734734edec4403b00ca95657 100644 (file)
@@ -3296,11 +3296,15 @@ int dev_get_phys_port_id(struct net_device *dev,
 int dev_get_phys_port_name(struct net_device *dev,
                           char *name, size_t len);
 int dev_change_proto_down(struct net_device *dev, bool proto_down);
-int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
-                     int fd, u32 flags);
 struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
 struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                                    struct netdev_queue *txq, int *ret);
+
+typedef int (*xdp_op_t)(struct net_device *dev, struct netdev_xdp *xdp);
+int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
+                     int fd, u32 flags);
+bool __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op);
+
 int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
 bool is_skb_forwardable(const struct net_device *dev,
index be378cf47fcc93fa2c89c6cd870f0a9fecd65211..b3044c2c62cbe8e856605129aa17f111e2a21493 100644 (file)
@@ -294,7 +294,7 @@ int xt_match_to_user(const struct xt_entry_match *m,
 int xt_target_to_user(const struct xt_entry_target *t,
                      struct xt_entry_target __user *u);
 int xt_data_to_user(void __user *dst, const void *src,
-                   int usersize, int size);
+                   int usersize, int size, int aligned_size);
 
 void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
                                 struct xt_counters_info *info, bool compat);
index a30efb437e6d1cfa42a75ec72997bf12b9cdf59d..e0cbf17af780e1d3e4c2be6bba351c9a27cebf88 100644 (file)
@@ -125,4 +125,9 @@ extern unsigned int ebt_do_table(struct sk_buff *skb,
 /* True if the target is not a standard target */
 #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
 
+static inline bool ebt_invalid_target(int target)
+{
+       return (target < -NUM_STANDARD_TARGETS || target >= 0);
+}
+
 #endif
index 0db37158a61d4e4e5af0d16d14c07510ef660330..6c8c5d8041b72ec01097d1c0563b793ea7449f1f 100644 (file)
@@ -27,8 +27,8 @@
 
 /* FC Port role bitmask - can merge with FC Port Roles in fc transport */
 #define FC_PORT_ROLE_NVME_INITIATOR    0x10
-#define FC_PORT_ROLE_NVME_TARGET       0x11
-#define FC_PORT_ROLE_NVME_DISCOVERY    0x12
+#define FC_PORT_ROLE_NVME_TARGET       0x20
+#define FC_PORT_ROLE_NVME_DISCOVERY    0x40
 
 
 /**
@@ -642,15 +642,7 @@ enum {
                 * sequence in one LLDD operation. Errors during Data
                 * sequence transmit must not allow RSP sequence to be sent.
                 */
-       NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED = (1 << 1),
-               /* Bit 1: When 0, the LLDD will deliver FCP CMD
-                * on the CPU it should be affinitized to. Thus work will
-                * be scheduled on the cpu received on. When 1, the LLDD
-                * may not deliver the CMD on the CPU it should be worked
-                * on. The transport should pick a cpu to schedule the work
-                * on.
-                */
-       NVMET_FCTGTFEAT_CMD_IN_ISR = (1 << 2),
+       NVMET_FCTGTFEAT_CMD_IN_ISR = (1 << 1),
                /* Bit 2: When 0, the LLDD is calling the cmd rcv handler
                 * in a non-isr context, allowing the transport to finish
                 * op completion in the calling context. When 1, the LLDD
@@ -658,7 +650,7 @@ enum {
                 * requiring the transport to transition to a workqueue
                 * for op completion.
                 */
-       NVMET_FCTGTFEAT_OPDONE_IN_ISR = (1 << 3),
+       NVMET_FCTGTFEAT_OPDONE_IN_ISR = (1 << 2),
                /* Bit 3: When 0, the LLDD is calling the op done handler
                 * in a non-isr context, allowing the transport to finish
                 * op completion in the calling context. When 1, the LLDD
index ec6b11deb77357444757691ec87d71d94b1b8953..1e0deb8e849458ca179c1df4734bb24f0e4cd748 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 
-typedef int const (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
 
 /*
  * Workarounds only applied to 32bit powermac machines
index a18e0783946b66eccba6a5b5faf77f2662d0a51a..787e7ad53d45f61cb045c047c610996de1141a7a 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef __LINUX_SOC_RENESAS_RCAR_RST_H__
 #define __LINUX_SOC_RENESAS_RCAR_RST_H__
 
+#if defined(CONFIG_ARCH_RCAR_GEN1) || defined(CONFIG_ARCH_RCAR_GEN2) || \
+    defined(CONFIG_ARCH_R8A7795) || defined(CONFIG_ARCH_R8A7796)
 int rcar_rst_read_mode_pins(u32 *mode);
+#else
+static inline int rcar_rst_read_mode_pins(u32 *mode) { return -ENODEV; }
+#endif
 
 #endif /* __LINUX_SOC_RENESAS_RCAR_RST_H__ */
index a469999a106dbc1869f7c90eccc313a90a6d17b0..50398b69ca4497401b7fae3ebc716655003f408c 100644 (file)
@@ -148,6 +148,7 @@ struct usb_hcd {
        unsigned                rh_registered:1;/* is root hub registered? */
        unsigned                rh_pollable:1;  /* may we poll the root hub? */
        unsigned                msix_enabled:1; /* driver has MSI-X enabled? */
+       unsigned                msi_enabled:1;  /* driver has MSI enabled? */
        unsigned                remove_phy:1;   /* auto-remove USB phy */
 
        /* The next flag is a stopgap, to be removed when all the HCDs
index e04fa7691e5d6873cd04e94816227d4a41275fa2..c519bb5b5bb8806089886caacaca4846fe3eeb98 100644 (file)
@@ -9,6 +9,7 @@
 
 #ifndef _NF_CONNTRACK_HELPER_H
 #define _NF_CONNTRACK_HELPER_H
+#include <linux/refcount.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_conntrack_expect.h>
@@ -26,6 +27,7 @@ struct nf_conntrack_helper {
        struct hlist_node hnode;        /* Internal use. */
 
        char name[NF_CT_HELPER_NAME_LEN]; /* name of the module */
+       refcount_t refcnt;
        struct module *me;              /* pointer to self */
        const struct nf_conntrack_expect_policy *expect_policy;
 
@@ -79,6 +81,8 @@ struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name,
 struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
                                                               u16 l3num,
                                                               u8 protonum);
+void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
+
 void nf_ct_helper_init(struct nf_conntrack_helper *helper,
                       u16 l3num, u16 protonum, const char *name,
                       u16 default_port, u16 spec_port, u32 id,
index 028faec8fc2799b0c176ac88b54fc6700e89f896..8a8bab8d7b15a8e9c746a899dcf474740e9f6f25 100644 (file)
@@ -176,7 +176,7 @@ struct nft_data_desc {
 int nft_data_init(const struct nft_ctx *ctx,
                  struct nft_data *data, unsigned int size,
                  struct nft_data_desc *desc, const struct nlattr *nla);
-void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
+void nft_data_release(const struct nft_data *data, enum nft_data_types type);
 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
                  enum nft_data_types type, unsigned int len);
 
index c383aa4edbf0c27980ef7aad22ff160c72b41bbd..6d30a01d281d4faa824129cb3921dbc3a77e7da3 100644 (file)
@@ -298,10 +298,10 @@ void x25_check_rbuf(struct sock *);
 
 /* sysctl_net_x25.c */
 #ifdef CONFIG_SYSCTL
-void x25_register_sysctl(void);
+int x25_register_sysctl(void);
 void x25_unregister_sysctl(void);
 #else
-static inline void x25_register_sysctl(void) {};
+static inline int x25_register_sysctl(void) { return 0; };
 static inline void x25_unregister_sysctl(void) {};
 #endif /* CONFIG_SYSCTL */
 
index 945a1f5f63c546c5521da5254a80664344ebd0ad..94dfa9def355f7f52805bba5ade3a32c304f989a 100644 (file)
@@ -132,6 +132,13 @@ enum bpf_attach_type {
  */
 #define BPF_F_ALLOW_OVERRIDE   (1U << 0)
 
+/* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the
+ * verifier will perform strict alignment checking as if the kernel
+ * has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set,
+ * and NET_IP_ALIGN defined to 2.
+ */
+#define BPF_F_STRICT_ALIGNMENT (1U << 0)
+
 #define BPF_PSEUDO_MAP_FD      1
 
 /* flags for BPF_MAP_UPDATE_ELEM command */
@@ -177,6 +184,7 @@ union bpf_attr {
                __u32           log_size;       /* size of user buffer */
                __aligned_u64   log_buf;        /* user supplied buffer */
                __u32           kern_version;   /* checked when prog_type=kprobe */
+               __u32           prog_flags;
        };
 
        struct { /* anonymous struct used by BPF_OBJ_* commands */
index 8e56ac70e0d1a3536a43aff83370e5b3bd5bb0b4..15ac20382ababeecafe2a336aa59a45e50d879e6 100644 (file)
@@ -888,9 +888,18 @@ enum {
 /* XDP section */
 
 #define XDP_FLAGS_UPDATE_IF_NOEXIST    (1U << 0)
-#define XDP_FLAGS_SKB_MODE             (2U << 0)
+#define XDP_FLAGS_SKB_MODE             (1U << 1)
+#define XDP_FLAGS_DRV_MODE             (1U << 2)
 #define XDP_FLAGS_MASK                 (XDP_FLAGS_UPDATE_IF_NOEXIST | \
-                                        XDP_FLAGS_SKB_MODE)
+                                        XDP_FLAGS_SKB_MODE | \
+                                        XDP_FLAGS_DRV_MODE)
+
+/* These are stored into IFLA_XDP_ATTACHED on dump. */
+enum {
+       XDP_ATTACHED_NONE = 0,
+       XDP_ATTACHED_DRV,
+       XDP_ATTACHED_SKB,
+};
 
 enum {
        IFLA_XDP_UNSPEC,
index 361297e96f5826360bb24f80de9089b83a9881ba..576c704e3fb8b13f358ae67b3a415417f2c37cb5 100644 (file)
@@ -22,6 +22,9 @@
  */
 #define USB_MAXCHILDREN                31
 
+/* See USB 3.1 spec Table 10-5 */
+#define USB_SS_MAXPORTS                15
+
 /*
  * Hub request types
  */
index fd2411fd69148cff375120316fba0a0e033541f6..265a0d854e3358c5c714af9cc3ab2bae8a4754b4 100644 (file)
@@ -783,7 +783,7 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
 EXPORT_SYMBOL_GPL(bpf_prog_get_type);
 
 /* last field in 'union bpf_attr' used by this command */
-#define        BPF_PROG_LOAD_LAST_FIELD kern_version
+#define        BPF_PROG_LOAD_LAST_FIELD prog_flags
 
 static int bpf_prog_load(union bpf_attr *attr)
 {
@@ -796,6 +796,9 @@ static int bpf_prog_load(union bpf_attr *attr)
        if (CHECK_ATTR(BPF_PROG_LOAD))
                return -EINVAL;
 
+       if (attr->prog_flags & ~BPF_F_STRICT_ALIGNMENT)
+               return -EINVAL;
+
        /* copy eBPF program license from user space */
        if (strncpy_from_user(license, u64_to_user_ptr(attr->license),
                              sizeof(license) - 1) < 0)
index c5b56c92f8e255d1b13634ad07c460969484f2f4..c72cd41f5b8b9c2e05b1f65aaf4730fb9a285ed0 100644 (file)
@@ -140,7 +140,7 @@ struct bpf_verifier_stack_elem {
        struct bpf_verifier_stack_elem *next;
 };
 
-#define BPF_COMPLEXITY_LIMIT_INSNS     65536
+#define BPF_COMPLEXITY_LIMIT_INSNS     98304
 #define BPF_COMPLEXITY_LIMIT_STACK     1024
 
 #define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA)
@@ -241,6 +241,12 @@ static void print_verifier_state(struct bpf_verifier_state *state)
                if (reg->max_value != BPF_REGISTER_MAX_RANGE)
                        verbose(",max_value=%llu",
                                (unsigned long long)reg->max_value);
+               if (reg->min_align)
+                       verbose(",min_align=%u", reg->min_align);
+               if (reg->aux_off)
+                       verbose(",aux_off=%u", reg->aux_off);
+               if (reg->aux_off_align)
+                       verbose(",aux_off_align=%u", reg->aux_off_align);
        }
        for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) {
                if (state->stack_slot_type[i] == STACK_SPILL)
@@ -466,6 +472,9 @@ static void init_reg_state(struct bpf_reg_state *regs)
                regs[i].imm = 0;
                regs[i].min_value = BPF_REGISTER_MIN_RANGE;
                regs[i].max_value = BPF_REGISTER_MAX_RANGE;
+               regs[i].min_align = 0;
+               regs[i].aux_off = 0;
+               regs[i].aux_off_align = 0;
        }
 
        /* frame pointer */
@@ -492,6 +501,7 @@ static void reset_reg_range_values(struct bpf_reg_state *regs, u32 regno)
 {
        regs[regno].min_value = BPF_REGISTER_MIN_RANGE;
        regs[regno].max_value = BPF_REGISTER_MAX_RANGE;
+       regs[regno].min_align = 0;
 }
 
 static void mark_reg_unknown_value_and_range(struct bpf_reg_state *regs,
@@ -779,17 +789,37 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno)
 }
 
 static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg,
-                                  int off, int size)
+                                  int off, int size, bool strict)
 {
-       if (reg->id && size != 1) {
-               verbose("Unknown alignment. Only byte-sized access allowed in packet access.\n");
-               return -EACCES;
+       int ip_align;
+       int reg_off;
+
+       /* Byte size accesses are always allowed. */
+       if (!strict || size == 1)
+               return 0;
+
+       reg_off = reg->off;
+       if (reg->id) {
+               if (reg->aux_off_align % size) {
+                       verbose("Packet access is only %u byte aligned, %d byte access not allowed\n",
+                               reg->aux_off_align, size);
+                       return -EACCES;
+               }
+               reg_off += reg->aux_off;
        }
 
-       /* skb->data is NET_IP_ALIGN-ed */
-       if ((NET_IP_ALIGN + reg->off + off) % size != 0) {
+       /* For platforms that do not have a Kconfig enabling
+        * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS the value of
+        * NET_IP_ALIGN is universally set to '2'.  And on platforms
+        * that do set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, we get
+        * to this code only in strict mode where we want to emulate
+        * the NET_IP_ALIGN==2 checking.  Therefore use an
+        * unconditional IP align value of '2'.
+        */
+       ip_align = 2;
+       if ((ip_align + reg_off + off) % size != 0) {
                verbose("misaligned packet access off %d+%d+%d size %d\n",
-                       NET_IP_ALIGN, reg->off, off, size);
+                       ip_align, reg_off, off, size);
                return -EACCES;
        }
 
@@ -797,9 +827,9 @@ static int check_pkt_ptr_alignment(const struct bpf_reg_state *reg,
 }
 
 static int check_val_ptr_alignment(const struct bpf_reg_state *reg,
-                                  int size)
+                                  int size, bool strict)
 {
-       if (size != 1) {
+       if (strict && size != 1) {
                verbose("Unknown alignment. Only byte-sized access allowed in value access.\n");
                return -EACCES;
        }
@@ -807,16 +837,20 @@ static int check_val_ptr_alignment(const struct bpf_reg_state *reg,
        return 0;
 }
 
-static int check_ptr_alignment(const struct bpf_reg_state *reg,
+static int check_ptr_alignment(struct bpf_verifier_env *env,
+                              const struct bpf_reg_state *reg,
                               int off, int size)
 {
+       bool strict = env->strict_alignment;
+
+       if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
+               strict = true;
+
        switch (reg->type) {
        case PTR_TO_PACKET:
-               return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ? 0 :
-                      check_pkt_ptr_alignment(reg, off, size);
+               return check_pkt_ptr_alignment(reg, off, size, strict);
        case PTR_TO_MAP_VALUE_ADJ:
-               return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ? 0 :
-                      check_val_ptr_alignment(reg, size);
+               return check_val_ptr_alignment(reg, size, strict);
        default:
                if (off % size != 0) {
                        verbose("misaligned access off %d size %d\n",
@@ -849,7 +883,7 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off,
        if (size < 0)
                return size;
 
-       err = check_ptr_alignment(reg, off, size);
+       err = check_ptr_alignment(env, reg, off, size);
        if (err)
                return err;
 
@@ -883,6 +917,8 @@ static int check_mem_access(struct bpf_verifier_env *env, u32 regno, int off,
                                                         value_regno);
                        /* note that reg.[id|off|range] == 0 */
                        state->regs[value_regno].type = reg_type;
+                       state->regs[value_regno].aux_off = 0;
+                       state->regs[value_regno].aux_off_align = 0;
                }
 
        } else if (reg->type == FRAME_PTR || reg->type == PTR_TO_STACK) {
@@ -1455,6 +1491,8 @@ add_imm:
                 */
                dst_reg->off += imm;
        } else {
+               bool had_id;
+
                if (src_reg->type == PTR_TO_PACKET) {
                        /* R6=pkt(id=0,off=0,r=62) R7=imm22; r7 += r6 */
                        tmp_reg = *dst_reg;  /* save r7 state */
@@ -1488,14 +1526,23 @@ add_imm:
                                src_reg->imm);
                        return -EACCES;
                }
+
+               had_id = (dst_reg->id != 0);
+
                /* dst_reg stays as pkt_ptr type and since some positive
                 * integer value was added to the pointer, increment its 'id'
                 */
                dst_reg->id = ++env->id_gen;
 
-               /* something was added to pkt_ptr, set range and off to zero */
+               /* something was added to pkt_ptr, set range to zero */
+               dst_reg->aux_off += dst_reg->off;
                dst_reg->off = 0;
                dst_reg->range = 0;
+               if (had_id)
+                       dst_reg->aux_off_align = min(dst_reg->aux_off_align,
+                                                    src_reg->min_align);
+               else
+                       dst_reg->aux_off_align = src_reg->min_align;
        }
        return 0;
 }
@@ -1669,6 +1716,13 @@ static void check_reg_overflow(struct bpf_reg_state *reg)
                reg->min_value = BPF_REGISTER_MIN_RANGE;
 }
 
+static u32 calc_align(u32 imm)
+{
+       if (!imm)
+               return 1U << 31;
+       return imm - ((imm - 1) & imm);
+}
+
 static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                                    struct bpf_insn *insn)
 {
@@ -1676,8 +1730,10 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
        s64 min_val = BPF_REGISTER_MIN_RANGE;
        u64 max_val = BPF_REGISTER_MAX_RANGE;
        u8 opcode = BPF_OP(insn->code);
+       u32 dst_align, src_align;
 
        dst_reg = &regs[insn->dst_reg];
+       src_align = 0;
        if (BPF_SRC(insn->code) == BPF_X) {
                check_reg_overflow(&regs[insn->src_reg]);
                min_val = regs[insn->src_reg].min_value;
@@ -1693,12 +1749,18 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                    regs[insn->src_reg].type != UNKNOWN_VALUE) {
                        min_val = BPF_REGISTER_MIN_RANGE;
                        max_val = BPF_REGISTER_MAX_RANGE;
+                       src_align = 0;
+               } else {
+                       src_align = regs[insn->src_reg].min_align;
                }
        } else if (insn->imm < BPF_REGISTER_MAX_RANGE &&
                   (s64)insn->imm > BPF_REGISTER_MIN_RANGE) {
                min_val = max_val = insn->imm;
+               src_align = calc_align(insn->imm);
        }
 
+       dst_align = dst_reg->min_align;
+
        /* We don't know anything about what was done to this register, mark it
         * as unknown.
         */
@@ -1723,18 +1785,21 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                        dst_reg->min_value += min_val;
                if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
                        dst_reg->max_value += max_val;
+               dst_reg->min_align = min(src_align, dst_align);
                break;
        case BPF_SUB:
                if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE)
                        dst_reg->min_value -= min_val;
                if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
                        dst_reg->max_value -= max_val;
+               dst_reg->min_align = min(src_align, dst_align);
                break;
        case BPF_MUL:
                if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE)
                        dst_reg->min_value *= min_val;
                if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
                        dst_reg->max_value *= max_val;
+               dst_reg->min_align = max(src_align, dst_align);
                break;
        case BPF_AND:
                /* Disallow AND'ing of negative numbers, ain't nobody got time
@@ -1746,17 +1811,23 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                else
                        dst_reg->min_value = 0;
                dst_reg->max_value = max_val;
+               dst_reg->min_align = max(src_align, dst_align);
                break;
        case BPF_LSH:
                /* Gotta have special overflow logic here, if we're shifting
                 * more than MAX_RANGE then just assume we have an invalid
                 * range.
                 */
-               if (min_val > ilog2(BPF_REGISTER_MAX_RANGE))
+               if (min_val > ilog2(BPF_REGISTER_MAX_RANGE)) {
                        dst_reg->min_value = BPF_REGISTER_MIN_RANGE;
-               else if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE)
-                       dst_reg->min_value <<= min_val;
-
+                       dst_reg->min_align = 1;
+               } else {
+                       if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE)
+                               dst_reg->min_value <<= min_val;
+                       if (!dst_reg->min_align)
+                               dst_reg->min_align = 1;
+                       dst_reg->min_align <<= min_val;
+               }
                if (max_val > ilog2(BPF_REGISTER_MAX_RANGE))
                        dst_reg->max_value = BPF_REGISTER_MAX_RANGE;
                else if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
@@ -1766,11 +1837,19 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env,
                /* RSH by a negative number is undefined, and the BPF_RSH is an
                 * unsigned shift, so make the appropriate casts.
                 */
-               if (min_val < 0 || dst_reg->min_value < 0)
+               if (min_val < 0 || dst_reg->min_value < 0) {
                        dst_reg->min_value = BPF_REGISTER_MIN_RANGE;
-               else
+               } else {
                        dst_reg->min_value =
                                (u64)(dst_reg->min_value) >> min_val;
+               }
+               if (min_val < 0) {
+                       dst_reg->min_align = 1;
+               } else {
+                       dst_reg->min_align >>= (u64) min_val;
+                       if (!dst_reg->min_align)
+                               dst_reg->min_align = 1;
+               }
                if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE)
                        dst_reg->max_value >>= max_val;
                break;
@@ -1872,6 +1951,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
                        regs[insn->dst_reg].imm = insn->imm;
                        regs[insn->dst_reg].max_value = insn->imm;
                        regs[insn->dst_reg].min_value = insn->imm;
+                       regs[insn->dst_reg].min_align = calc_align(insn->imm);
                }
 
        } else if (opcode > BPF_END) {
@@ -2564,6 +2644,7 @@ peek_stack:
                                env->explored_states[t + 1] = STATE_LIST_MARK;
                } else {
                        /* conditional jump with two edges */
+                       env->explored_states[t] = STATE_LIST_MARK;
                        ret = push_insn(t, t + 1, FALLTHROUGH, env);
                        if (ret == 1)
                                goto peek_stack;
@@ -2722,6 +2803,12 @@ static bool states_equal(struct bpf_verifier_env *env,
                     rcur->type != NOT_INIT))
                        continue;
 
+               /* Don't care about the reg->id in this case. */
+               if (rold->type == PTR_TO_MAP_VALUE_OR_NULL &&
+                   rcur->type == PTR_TO_MAP_VALUE_OR_NULL &&
+                   rold->map_ptr == rcur->map_ptr)
+                       continue;
+
                if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET &&
                    compare_ptrs_to_packet(rold, rcur))
                        continue;
@@ -2856,8 +2943,15 @@ static int do_check(struct bpf_verifier_env *env)
                        goto process_bpf_exit;
                }
 
-               if (log_level && do_print_state) {
-                       verbose("\nfrom %d to %d:", prev_insn_idx, insn_idx);
+               if (need_resched())
+                       cond_resched();
+
+               if (log_level > 1 || (log_level && do_print_state)) {
+                       if (log_level > 1)
+                               verbose("%d:", insn_idx);
+                       else
+                               verbose("\nfrom %d to %d:",
+                                       prev_insn_idx, insn_idx);
                        print_verifier_state(&env->cur_state);
                        do_print_state = false;
                }
@@ -3494,6 +3588,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
        } else {
                log_level = 0;
        }
+       if (attr->prog_flags & BPF_F_STRICT_ALIGNMENT)
+               env->strict_alignment = true;
+       else
+               env->strict_alignment = false;
 
        ret = replace_map_fd_with_map_ptr(env);
        if (ret < 0)
@@ -3599,6 +3697,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct bpf_ext_analyzer_ops *ops,
        mutex_lock(&bpf_verifier_lock);
 
        log_level = 0;
+       env->strict_alignment = false;
 
        env->explored_states = kcalloc(env->prog->len,
                                       sizeof(struct bpf_verifier_state_list *),
index 06d759ab4c62ff090ab51715eaf0bc4fcabc250e..aa1076c5e4a9f3a5d9e6f58fef1c6f34e332de8c 100644 (file)
@@ -1845,11 +1845,13 @@ static __latent_entropy struct task_struct *copy_process(
        */
        recalc_sigpending();
        if (signal_pending(current)) {
-               spin_unlock(&current->sighand->siglock);
-               write_unlock_irq(&tasklist_lock);
                retval = -ERESTARTNOINTR;
                goto bad_fork_cancel_cgroup;
        }
+       if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) {
+               retval = -ENOMEM;
+               goto bad_fork_cancel_cgroup;
+       }
 
        if (likely(p->pid)) {
                ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
@@ -1907,6 +1909,8 @@ static __latent_entropy struct task_struct *copy_process(
        return p;
 
 bad_fork_cancel_cgroup:
+       spin_unlock(&current->sighand->siglock);
+       write_unlock_irq(&tasklist_lock);
        cgroup_cancel_fork(p);
 bad_fork_free_pid:
        cgroup_threadgroup_change_end(current);
index 686be4b73018886d5b676d99cc5f5645cf408259..c94da688ee9b30ff9e746372b20a0c30f4c8cf5f 100644 (file)
@@ -880,8 +880,8 @@ irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
        if (!desc)
                return;
 
-       __irq_do_set_handler(desc, handle, 1, NULL);
        desc->irq_common_data.handler_data = data;
+       __irq_do_set_handler(desc, handle, 1, NULL);
 
        irq_put_desc_busunlock(desc, flags);
 }
index 7367e0ec6f8188973a0ee63539cd9a8485e47585..2d2d3a568e4e8b3aeedb16711c90e660f698d6cf 100644 (file)
@@ -595,7 +595,7 @@ static void kprobe_optimizer(struct work_struct *work)
 }
 
 /* Wait for completing optimization and unoptimization */
-static void wait_for_kprobe_optimizer(void)
+void wait_for_kprobe_optimizer(void)
 {
        mutex_lock(&kprobe_mutex);
 
@@ -2183,6 +2183,12 @@ static int kprobes_module_callback(struct notifier_block *nb,
                                 * The vaddr this probe is installed will soon
                                 * be vfreed buy not synced to disk. Hence,
                                 * disarming the breakpoint isn't needed.
+                                *
+                                * Note, this will also move any optimized probes
+                                * that are pending to be removed from their
+                                * corresponding lists to the freeing_list and
+                                * will not be touched by the delayed
+                                * kprobe_optimizer work handler.
                                 */
                                kill_kprobe(p);
                        }
index d1f3e9f558b84058e4f8ec88fdfddc647d2f704e..74a5a7255b4d9cb473cc7708d851c64402cca942 100644 (file)
@@ -277,7 +277,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
         * if reparented.
         */
        for (;;) {
-               set_current_state(TASK_UNINTERRUPTIBLE);
+               set_current_state(TASK_INTERRUPTIBLE);
                if (pid_ns->nr_hashed == init_pids)
                        break;
                schedule();
index 3b1e0f3ad07fa69d9524bcb72d1c6d0bab1a9ad8..fa46606f33565613d2ef13a1e948f2bae0dfaa8b 100644 (file)
@@ -1425,7 +1425,7 @@ static unsigned int nr_meta_pages;
  * Numbers of normal and highmem page frames allocated for hibernation image
  * before suspending devices.
  */
-unsigned int alloc_normal, alloc_highmem;
+static unsigned int alloc_normal, alloc_highmem;
 /*
  * Memory bitmap used for marking saveable pages (during hibernation) or
  * hibernation image pages (during restore)
index 76877a62b5fa374f0daa93f1180ce853ba32fc0c..622eed1b7658301a94a645c4426598b0096a8ab9 100644 (file)
@@ -245,11 +245,10 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
        sugov_update_commit(sg_policy, time, next_f);
 }
 
-static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu)
+static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time)
 {
        struct sugov_policy *sg_policy = sg_cpu->sg_policy;
        struct cpufreq_policy *policy = sg_policy->policy;
-       u64 last_freq_update_time = sg_policy->last_freq_update_time;
        unsigned long util = 0, max = 1;
        unsigned int j;
 
@@ -265,7 +264,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu)
                 * enough, don't take the CPU into account as it probably is
                 * idle now (and clear iowait_boost for it).
                 */
-               delta_ns = last_freq_update_time - j_sg_cpu->last_update;
+               delta_ns = time - j_sg_cpu->last_update;
                if (delta_ns > TICK_NSEC) {
                        j_sg_cpu->iowait_boost = 0;
                        continue;
@@ -309,7 +308,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
                if (flags & SCHED_CPUFREQ_RT_DL)
                        next_f = sg_policy->policy->cpuinfo.max_freq;
                else
-                       next_f = sugov_next_freq_shared(sg_cpu);
+                       next_f = sugov_next_freq_shared(sg_cpu, time);
 
                sugov_update_commit(sg_policy, time, next_f);
        }
index bd8ae8d5ae9ca865f3738c6b4df579a3a1ca12cc..193c5f5e3f7988e8d27eed5c4292e2345e3c5bf7 100644 (file)
@@ -1662,14 +1662,14 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
                goto out;
 
        if (attr == &dev_attr_act_mask) {
-               if (sscanf(buf, "%llx", &value) != 1) {
+               if (kstrtoull(buf, 0, &value)) {
                        /* Assume it is a list of trace category names */
                        ret = blk_trace_str2mask(buf);
                        if (ret < 0)
                                goto out;
                        value = ret;
                }
-       } else if (sscanf(buf, "%llu", &value) != 1)
+       } else if (kstrtoull(buf, 0, &value))
                goto out;
 
        ret = -ENXIO;
index 39dca4e86a94f0867c29aaa29b47d881eefd02e8..74fdfe9ed3dba7fa659cb11feafac25919984bbb 100644 (file)
@@ -4144,9 +4144,9 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
        int i, ret = -ENODEV;
        int size;
 
-       if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
+       if (!glob || !strlen(glob) || !strcmp(glob, "*"))
                func_g.search = NULL;
-       else if (glob) {
+       else {
                int not;
 
                func_g.type = filter_parse_regex(glob, strlen(glob),
@@ -4256,6 +4256,14 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
        return ret;
 }
 
+void clear_ftrace_function_probes(struct trace_array *tr)
+{
+       struct ftrace_func_probe *probe, *n;
+
+       list_for_each_entry_safe(probe, n, &tr->func_probes, list)
+               unregister_ftrace_function_probe_func(NULL, tr, probe->probe_ops);
+}
+
 static LIST_HEAD(ftrace_commands);
 static DEFINE_MUTEX(ftrace_cmd_mutex);
 
index c4536c4490217a2e6b59e423c70c0f1836a34a9d..1122f151466f64425089b9b9ecbd4b1a7584ba8a 100644 (file)
@@ -1558,7 +1558,7 @@ static __init int init_trace_selftests(void)
 
        return 0;
 }
-early_initcall(init_trace_selftests);
+core_initcall(init_trace_selftests);
 #else
 static inline int run_tracer_selftest(struct tracer *type)
 {
@@ -2568,7 +2568,36 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
 void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
                   int pc)
 {
-       __ftrace_trace_stack(tr->trace_buffer.buffer, flags, skip, pc, NULL);
+       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+
+       if (rcu_is_watching()) {
+               __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
+               return;
+       }
+
+       /*
+        * When an NMI triggers, RCU is enabled via rcu_nmi_enter(),
+        * but if the above rcu_is_watching() failed, then the NMI
+        * triggered someplace critical, and rcu_irq_enter() should
+        * not be called from NMI.
+        */
+       if (unlikely(in_nmi()))
+               return;
+
+       /*
+        * It is possible that a function is being traced in a
+        * location that RCU is not watching. A call to
+        * rcu_irq_enter() will make sure that it is, but there's
+        * a few internal rcu functions that could be traced
+        * where that wont work either. In those cases, we just
+        * do nothing.
+        */
+       if (unlikely(rcu_irq_enter_disabled()))
+               return;
+
+       rcu_irq_enter_irqson();
+       __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
+       rcu_irq_exit_irqson();
 }
 
 /**
@@ -7550,6 +7579,7 @@ static int instance_rmdir(const char *name)
        }
 
        tracing_set_nop(tr);
+       clear_ftrace_function_probes(tr);
        event_trace_del_tracer(tr);
        ftrace_clear_pids(tr);
        ftrace_destroy_function_files(tr);
index 291a1bca5748870011c70e639fe802785945a0a6..39fd77330aabb12a68d2104d9c20e81ea739f20e 100644 (file)
@@ -980,6 +980,7 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr,
 extern int
 unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
                                      struct ftrace_probe_ops *ops);
+extern void clear_ftrace_function_probes(struct trace_array *tr);
 
 int register_ftrace_command(struct ftrace_func_command *cmd);
 int unregister_ftrace_command(struct ftrace_func_command *cmd);
@@ -998,6 +999,10 @@ static inline __init int unregister_ftrace_command(char *cmd_name)
 {
        return -EINVAL;
 }
+static inline void clear_ftrace_function_probes(struct trace_array *tr)
+{
+}
+
 /*
  * The ops parameter passed in is usually undefined.
  * This must be a macro.
index 8485f6738a87cba32a070543b4ae7b8c434ad04c..c129fca6ec993a85aeb30c7e3aa69254e3f5ac16 100644 (file)
@@ -1535,6 +1535,11 @@ static __init int kprobe_trace_self_tests_init(void)
 
 end:
        release_all_trace_kprobes();
+       /*
+        * Wait for the optimizer work to finish. Otherwise it might fiddle
+        * with probes in already freed __init text.
+        */
+       wait_for_kprobe_optimizer();
        if (warn)
                pr_cont("NG: Some tests are failed. Please check them.\n");
        else
index 71e85643b3f96db09de3330263f556fedba65257..6ad3e043c6174ae97a82525688988e740d87fd29 100644 (file)
@@ -454,8 +454,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
                        goto error_xenbus;
        }
        priv->tag = xenbus_read(xbt, dev->nodename, "tag", NULL);
-       if (!priv->tag) {
-               ret = -EINVAL;
+       if (IS_ERR(priv->tag)) {
+               ret = PTR_ERR(priv->tag);
                goto error_xenbus;
        }
        ret = xenbus_transaction_end(xbt, 0);
@@ -525,7 +525,7 @@ static struct xenbus_driver xen_9pfs_front_driver = {
        .otherend_changed = xen_9pfs_front_changed,
 };
 
-int p9_trans_xen_init(void)
+static int p9_trans_xen_init(void)
 {
        if (!xen_domain())
                return -ENODEV;
@@ -537,7 +537,7 @@ int p9_trans_xen_init(void)
 }
 module_init(p9_trans_xen_init);
 
-void p9_trans_xen_exit(void)
+static void p9_trans_xen_exit(void)
 {
        v9fs_unregister_trans(&p9_xen_trans);
        return xenbus_unregister_driver(&xen_9pfs_front_driver);
index c5ce7745b230fa3e67b66ba211be00d66cdc52da..574f78824d8a2ae53751bbe1849e53502bc575be 100644 (file)
@@ -835,6 +835,13 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[])
                        return -EPROTONOSUPPORT;
                }
        }
+
+       if (data[IFLA_BR_VLAN_DEFAULT_PVID]) {
+               __u16 defpvid = nla_get_u16(data[IFLA_BR_VLAN_DEFAULT_PVID]);
+
+               if (defpvid >= VLAN_VID_MASK)
+                       return -EINVAL;
+       }
 #endif
 
        return 0;
index 08341d2aa9c946d7bdd6e0d599e31ba96557a290..0db8102995a506d64ece0de48b7266ccf3839ba8 100644 (file)
@@ -179,6 +179,7 @@ static void br_stp_start(struct net_bridge *br)
                br_debug(br, "using kernel STP\n");
 
                /* To start timers on any ports left in blocking */
+               mod_timer(&br->hello_timer, jiffies + br->hello_time);
                br_port_state_selection(br);
        }
 
index c98b3e5c140a5f30a28fd748408cf5e949a032b6..60b6fe277a8b0c90faad0dfcda87f149ceaa5552 100644 (file)
@@ -40,7 +40,7 @@ static void br_hello_timer_expired(unsigned long arg)
        if (br->dev->flags & IFF_UP) {
                br_config_bpdu_generation(br);
 
-               if (br->stp_enabled != BR_USER_STP)
+               if (br->stp_enabled == BR_KERNEL_STP)
                        mod_timer(&br->hello_timer,
                                  round_jiffies(jiffies + br->hello_time));
        }
index 5929309beaa1d5d310a19029364693c0b0355772..db85230e49c3b7e97093d54a1d7625d9145dfeb4 100644 (file)
@@ -68,6 +68,9 @@ static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
        if (e->ethproto != htons(ETH_P_ARP) ||
            e->invflags & EBT_IPROTO)
                return -EINVAL;
+       if (ebt_invalid_target(info->target))
+               return -EINVAL;
+
        return 0;
 }
 
index 9ec0c9f908fa712b18bfa25c87aa7bce12cee786..9c6e619f452bc96770a8e340d3879adce6dadd2a 100644 (file)
@@ -1373,7 +1373,8 @@ static inline int ebt_obj_to_user(char __user *um, const char *_name,
        strlcpy(name, _name, sizeof(name));
        if (copy_to_user(um, name, EBT_FUNCTION_MAXNAMELEN) ||
            put_user(datasize, (int __user *)(um + EBT_FUNCTION_MAXNAMELEN)) ||
-           xt_data_to_user(um + entrysize, data, usersize, datasize))
+           xt_data_to_user(um + entrysize, data, usersize, datasize,
+                           XT_ALIGN(datasize)))
                return -EFAULT;
 
        return 0;
@@ -1658,7 +1659,8 @@ static int compat_match_to_user(struct ebt_entry_match *m, void __user **dstptr,
                if (match->compat_to_user(cm->data, m->data))
                        return -EFAULT;
        } else {
-               if (xt_data_to_user(cm->data, m->data, match->usersize, msize))
+               if (xt_data_to_user(cm->data, m->data, match->usersize, msize,
+                                   COMPAT_XT_ALIGN(msize)))
                        return -EFAULT;
        }
 
@@ -1687,7 +1689,8 @@ static int compat_target_to_user(struct ebt_entry_target *t,
                if (target->compat_to_user(cm->data, t->data))
                        return -EFAULT;
        } else {
-               if (xt_data_to_user(cm->data, t->data, target->usersize, tsize))
+               if (xt_data_to_user(cm->data, t->data, target->usersize, tsize,
+                                   COMPAT_XT_ALIGN(tsize)))
                        return -EFAULT;
        }
 
index 96cf83da0d66b2db07d5504c4c3aec7da735ea46..fca407b4a6ea178d9224949bc57f89a26c97c5c1 100644 (file)
@@ -6852,6 +6852,32 @@ int dev_change_proto_down(struct net_device *dev, bool proto_down)
 }
 EXPORT_SYMBOL(dev_change_proto_down);
 
+bool __dev_xdp_attached(struct net_device *dev, xdp_op_t xdp_op)
+{
+       struct netdev_xdp xdp;
+
+       memset(&xdp, 0, sizeof(xdp));
+       xdp.command = XDP_QUERY_PROG;
+
+       /* Query must always succeed. */
+       WARN_ON(xdp_op(dev, &xdp) < 0);
+       return xdp.prog_attached;
+}
+
+static int dev_xdp_install(struct net_device *dev, xdp_op_t xdp_op,
+                          struct netlink_ext_ack *extack,
+                          struct bpf_prog *prog)
+{
+       struct netdev_xdp xdp;
+
+       memset(&xdp, 0, sizeof(xdp));
+       xdp.command = XDP_SETUP_PROG;
+       xdp.extack = extack;
+       xdp.prog = prog;
+
+       return xdp_op(dev, &xdp);
+}
+
 /**
  *     dev_change_xdp_fd - set or clear a bpf program for a device rx path
  *     @dev: device
@@ -6864,41 +6890,34 @@ EXPORT_SYMBOL(dev_change_proto_down);
 int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
                      int fd, u32 flags)
 {
-       int (*xdp_op)(struct net_device *dev, struct netdev_xdp *xdp);
        const struct net_device_ops *ops = dev->netdev_ops;
        struct bpf_prog *prog = NULL;
-       struct netdev_xdp xdp;
+       xdp_op_t xdp_op, xdp_chk;
        int err;
 
        ASSERT_RTNL();
 
-       xdp_op = ops->ndo_xdp;
+       xdp_op = xdp_chk = ops->ndo_xdp;
+       if (!xdp_op && (flags & XDP_FLAGS_DRV_MODE))
+               return -EOPNOTSUPP;
        if (!xdp_op || (flags & XDP_FLAGS_SKB_MODE))
                xdp_op = generic_xdp_install;
+       if (xdp_op == xdp_chk)
+               xdp_chk = generic_xdp_install;
 
        if (fd >= 0) {
-               if (flags & XDP_FLAGS_UPDATE_IF_NOEXIST) {
-                       memset(&xdp, 0, sizeof(xdp));
-                       xdp.command = XDP_QUERY_PROG;
-
-                       err = xdp_op(dev, &xdp);
-                       if (err < 0)
-                               return err;
-                       if (xdp.prog_attached)
-                               return -EBUSY;
-               }
+               if (xdp_chk && __dev_xdp_attached(dev, xdp_chk))
+                       return -EEXIST;
+               if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) &&
+                   __dev_xdp_attached(dev, xdp_op))
+                       return -EBUSY;
 
                prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_XDP);
                if (IS_ERR(prog))
                        return PTR_ERR(prog);
        }
 
-       memset(&xdp, 0, sizeof(xdp));
-       xdp.command = XDP_SETUP_PROG;
-       xdp.extack = extack;
-       xdp.prog = prog;
-
-       err = xdp_op(dev, &xdp);
+       err = dev_xdp_install(dev, xdp_op, extack, prog);
        if (err < 0 && prog)
                bpf_prog_put(prog);
 
index 58b0bcc125b5559f299dc2f195deccb5c43d0844..d274f81fcc2c08f1e85df4ed00b9a034f3ae0739 100644 (file)
@@ -1132,10 +1132,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                lladdr = neigh->ha;
        }
 
-       if (new & NUD_CONNECTED)
-               neigh->confirmed = jiffies;
-       neigh->updated = jiffies;
-
        /* If entry was valid and address is not changed,
           do not change entry state, if new one is STALE.
         */
@@ -1157,6 +1153,16 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                }
        }
 
+       /* Update timestamps only once we know we will make a change to the
+        * neighbour entry. Otherwise we risk to move the locktime window with
+        * noop updates and ignore relevant ARP updates.
+        */
+       if (new != old || lladdr != neigh->ha) {
+               if (new & NUD_CONNECTED)
+                       neigh->confirmed = jiffies;
+               neigh->updated = jiffies;
+       }
+
        if (new != old) {
                neigh_del_timer(neigh);
                if (new & NUD_PROBE)
index bcb0f610ee422a12ad6b8ae41763296ba0fa3c6a..49a279a7cc15b0d2409236f53a0629ccc927e07c 100644 (file)
@@ -899,8 +899,7 @@ static size_t rtnl_port_size(const struct net_device *dev,
 static size_t rtnl_xdp_size(void)
 {
        size_t xdp_size = nla_total_size(0) +   /* nest IFLA_XDP */
-                         nla_total_size(1) +   /* XDP_ATTACHED */
-                         nla_total_size(4);    /* XDP_FLAGS */
+                         nla_total_size(1);    /* XDP_ATTACHED */
 
        return xdp_size;
 }
@@ -1247,37 +1246,34 @@ static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
+static u8 rtnl_xdp_attached_mode(struct net_device *dev)
+{
+       const struct net_device_ops *ops = dev->netdev_ops;
+
+       ASSERT_RTNL();
+
+       if (rcu_access_pointer(dev->xdp_prog))
+               return XDP_ATTACHED_SKB;
+       if (ops->ndo_xdp && __dev_xdp_attached(dev, ops->ndo_xdp))
+               return XDP_ATTACHED_DRV;
+
+       return XDP_ATTACHED_NONE;
+}
+
 static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
 {
        struct nlattr *xdp;
-       u32 xdp_flags = 0;
-       u8 val = 0;
        int err;
 
        xdp = nla_nest_start(skb, IFLA_XDP);
        if (!xdp)
                return -EMSGSIZE;
-       if (rcu_access_pointer(dev->xdp_prog)) {
-               xdp_flags = XDP_FLAGS_SKB_MODE;
-               val = 1;
-       } else if (dev->netdev_ops->ndo_xdp) {
-               struct netdev_xdp xdp_op = {};
-
-               xdp_op.command = XDP_QUERY_PROG;
-               err = dev->netdev_ops->ndo_xdp(dev, &xdp_op);
-               if (err)
-                       goto err_cancel;
-               val = xdp_op.prog_attached;
-       }
-       err = nla_put_u8(skb, IFLA_XDP_ATTACHED, val);
+
+       err = nla_put_u8(skb, IFLA_XDP_ATTACHED,
+                        rtnl_xdp_attached_mode(dev));
        if (err)
                goto err_cancel;
 
-       if (xdp_flags) {
-               err = nla_put_u32(skb, IFLA_XDP_FLAGS, xdp_flags);
-               if (err)
-                       goto err_cancel;
-       }
        nla_nest_end(skb, xdp);
        return 0;
 
@@ -1631,13 +1627,13 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
                                               cb->nlh->nlmsg_seq, 0,
                                               flags,
                                               ext_filter_mask);
-                       /* If we ran out of room on the first message,
-                        * we're in trouble
-                        */
-                       WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
 
-                       if (err < 0)
-                               goto out;
+                       if (err < 0) {
+                               if (likely(skb->len))
+                                       goto out;
+
+                               goto out_err;
+                       }
 
                        nl_dump_check_consistent(cb, nlmsg_hdr(skb));
 cont:
@@ -1645,10 +1641,12 @@ cont:
                }
        }
 out:
+       err = skb->len;
+out_err:
        cb->args[1] = idx;
        cb->args[0] = h;
 
-       return skb->len;
+       return err;
 }
 
 int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
@@ -2199,6 +2197,11 @@ static int do_setlink(const struct sk_buff *skb,
                                err = -EINVAL;
                                goto errout;
                        }
+                       if ((xdp_flags & XDP_FLAGS_SKB_MODE) &&
+                           (xdp_flags & XDP_FLAGS_DRV_MODE)) {
+                               err = -EINVAL;
+                               goto errout;
+                       }
                }
 
                if (xdp[IFLA_XDP_FD]) {
@@ -3452,8 +3455,12 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
                                err = br_dev->netdev_ops->ndo_bridge_getlink(
                                                skb, portid, seq, dev,
                                                filter_mask, NLM_F_MULTI);
-                               if (err < 0 && err != -EOPNOTSUPP)
-                                       break;
+                               if (err < 0 && err != -EOPNOTSUPP) {
+                                       if (likely(skb->len))
+                                               break;
+
+                                       goto out_err;
+                               }
                        }
                        idx++;
                }
@@ -3464,16 +3471,22 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
                                                              seq, dev,
                                                              filter_mask,
                                                              NLM_F_MULTI);
-                               if (err < 0 && err != -EOPNOTSUPP)
-                                       break;
+                               if (err < 0 && err != -EOPNOTSUPP) {
+                                       if (likely(skb->len))
+                                               break;
+
+                                       goto out_err;
+                               }
                        }
                        idx++;
                }
        }
+       err = skb->len;
+out_err:
        rcu_read_unlock();
        cb->args[0] = idx;
 
-       return skb->len;
+       return err;
 }
 
 static inline size_t bridge_nlmsg_size(void)
index 79c6aee6af9b817bd7086f04ae8f46342a3bf4b6..727f924b7f91f495d9e7a4e7297c9c937d3258ed 100644 (file)
 
 #include <trace/events/sock.h>
 
-#ifdef CONFIG_INET
 #include <net/tcp.h>
-#endif
-
 #include <net/busy_poll.h>
 
 static DEFINE_MUTEX(proto_list_mutex);
@@ -1803,28 +1800,24 @@ EXPORT_SYMBOL(skb_set_owner_w);
  * delay queue. We want to allow the owner socket to send more
  * packets, as if they were already TX completed by a typical driver.
  * But we also want to keep skb->sk set because some packet schedulers
- * rely on it (sch_fq for example). So we set skb->truesize to a small
- * amount (1) and decrease sk_wmem_alloc accordingly.
+ * rely on it (sch_fq for example).
  */
 void skb_orphan_partial(struct sk_buff *skb)
 {
-       /* If this skb is a TCP pure ACK or already went here,
-        * we have nothing to do. 2 is already a very small truesize.
-        */
-       if (skb->truesize <= 2)
+       if (skb_is_tcp_pure_ack(skb))
                return;
 
-       /* TCP stack sets skb->ooo_okay based on sk_wmem_alloc,
-        * so we do not completely orphan skb, but transfert all
-        * accounted bytes but one, to avoid unexpected reorders.
-        */
        if (skb->destructor == sock_wfree
 #ifdef CONFIG_INET
            || skb->destructor == tcp_wfree
 #endif
                ) {
-               atomic_sub(skb->truesize - 1, &skb->sk->sk_wmem_alloc);
-               skb->truesize = 1;
+               struct sock *sk = skb->sk;
+
+               if (atomic_inc_not_zero(&sk->sk_refcnt)) {
+                       atomic_sub(skb->truesize, &sk->sk_wmem_alloc);
+                       skb->destructor = sock_efree;
+               }
        } else {
                skb_orphan(skb);
        }
index 840f14aaa01635e0f6fb62232b67814736c84b5d..992621172220d136a1114a58f1c0e75219c57ea4 100644 (file)
@@ -426,6 +426,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
                newsk->sk_backlog_rcv = dccp_v4_do_rcv;
                newnp->pktoptions  = NULL;
                newnp->opt         = NULL;
+               newnp->ipv6_mc_list = NULL;
+               newnp->ipv6_ac_list = NULL;
+               newnp->ipv6_fl_list = NULL;
                newnp->mcast_oif   = inet6_iif(skb);
                newnp->mcast_hops  = ipv6_hdr(skb)->hop_limit;
 
@@ -490,6 +493,9 @@ static struct sock *dccp_v6_request_recv_sock(const struct sock *sk,
        /* Clone RX bits */
        newnp->rxopt.all = np->rxopt.all;
 
+       newnp->ipv6_mc_list = NULL;
+       newnp->ipv6_ac_list = NULL;
+       newnp->ipv6_fl_list = NULL;
        newnp->pktoptions = NULL;
        newnp->opt        = NULL;
        newnp->mcast_oif  = inet6_iif(skb);
index 0937b34c27cacb2dec73a67a76ff11fe26722500..ae96e6f3e0cb048e6a9273421343daf3582e9463 100644 (file)
@@ -641,6 +641,32 @@ void arp_xmit(struct sk_buff *skb)
 }
 EXPORT_SYMBOL(arp_xmit);
 
+static bool arp_is_garp(struct net *net, struct net_device *dev,
+                       int *addr_type, __be16 ar_op,
+                       __be32 sip, __be32 tip,
+                       unsigned char *sha, unsigned char *tha)
+{
+       bool is_garp = tip == sip;
+
+       /* Gratuitous ARP _replies_ also require target hwaddr to be
+        * the same as source.
+        */
+       if (is_garp && ar_op == htons(ARPOP_REPLY))
+               is_garp =
+                       /* IPv4 over IEEE 1394 doesn't provide target
+                        * hardware address field in its ARP payload.
+                        */
+                       tha &&
+                       !memcmp(tha, sha, dev->addr_len);
+
+       if (is_garp) {
+               *addr_type = inet_addr_type_dev_table(net, dev, sip);
+               if (*addr_type != RTN_UNICAST)
+                       is_garp = false;
+       }
+       return is_garp;
+}
+
 /*
  *     Process an arp request.
  */
@@ -653,6 +679,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
        unsigned char *arp_ptr;
        struct rtable *rt;
        unsigned char *sha;
+       unsigned char *tha = NULL;
        __be32 sip, tip;
        u16 dev_type = dev->type;
        int addr_type;
@@ -724,6 +751,7 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
                break;
 #endif
        default:
+               tha = arp_ptr;
                arp_ptr += dev->addr_len;
        }
        memcpy(&tip, arp_ptr, 4);
@@ -835,19 +863,25 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
 
        n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
 
-       if (IN_DEV_ARP_ACCEPT(in_dev)) {
-               unsigned int addr_type = inet_addr_type_dev_table(net, dev, sip);
+       if (n || IN_DEV_ARP_ACCEPT(in_dev)) {
+               addr_type = -1;
+               is_garp = arp_is_garp(net, dev, &addr_type, arp->ar_op,
+                                     sip, tip, sha, tha);
+       }
 
+       if (IN_DEV_ARP_ACCEPT(in_dev)) {
                /* Unsolicited ARP is not accepted by default.
                   It is possible, that this option should be enabled for some
                   devices (strip is candidate)
                 */
-               is_garp = arp->ar_op == htons(ARPOP_REQUEST) && tip == sip &&
-                         addr_type == RTN_UNICAST;
-
                if (!n &&
-                   ((arp->ar_op == htons(ARPOP_REPLY)  &&
-                               addr_type == RTN_UNICAST) || is_garp))
+                   (is_garp ||
+                    (arp->ar_op == htons(ARPOP_REPLY) &&
+                     (addr_type == RTN_UNICAST ||
+                      (addr_type < 0 &&
+                       /* postpone calculation to as late as possible */
+                       inet_addr_type_dev_table(net, dev, sip) ==
+                               RTN_UNICAST)))))
                        n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
        }
 
index 39bd1edee67649af86eb582c0ea478713360a506..83e3ed258467dbfd620bd27d48a0b33f5ef7a067 100644 (file)
@@ -763,7 +763,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
        unsigned int e = 0, s_e;
        struct fib_table *tb;
        struct hlist_head *head;
-       int dumped = 0;
+       int dumped = 0, err;
 
        if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
            ((struct rtmsg *) nlmsg_data(cb->nlh))->rtm_flags & RTM_F_CLONED)
@@ -783,20 +783,27 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
                        if (dumped)
                                memset(&cb->args[2], 0, sizeof(cb->args) -
                                                 2 * sizeof(cb->args[0]));
-                       if (fib_table_dump(tb, skb, cb) < 0)
-                               goto out;
+                       err = fib_table_dump(tb, skb, cb);
+                       if (err < 0) {
+                               if (likely(skb->len))
+                                       goto out;
+
+                               goto out_err;
+                       }
                        dumped = 1;
 next:
                        e++;
                }
        }
 out:
+       err = skb->len;
+out_err:
        rcu_read_unlock();
 
        cb->args[1] = e;
        cb->args[0] = h;
 
-       return skb->len;
+       return err;
 }
 
 /* Prepare and feed intra-kernel routing request.
index 1201409ba1dcb18ee028003b065410b87bf4a602..51182ff2b4415238210e83208bf7f45b5fb55326 100644 (file)
@@ -1983,6 +1983,8 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
 
        /* rcu_read_lock is hold by caller */
        hlist_for_each_entry_rcu(fa, &l->leaf, fa_list) {
+               int err;
+
                if (i < s_i) {
                        i++;
                        continue;
@@ -1993,17 +1995,14 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
                        continue;
                }
 
-               if (fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
-                                 cb->nlh->nlmsg_seq,
-                                 RTM_NEWROUTE,
-                                 tb->tb_id,
-                                 fa->fa_type,
-                                 xkey,
-                                 KEYLENGTH - fa->fa_slen,
-                                 fa->fa_tos,
-                                 fa->fa_info, NLM_F_MULTI) < 0) {
+               err = fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
+                                   cb->nlh->nlmsg_seq, RTM_NEWROUTE,
+                                   tb->tb_id, fa->fa_type,
+                                   xkey, KEYLENGTH - fa->fa_slen,
+                                   fa->fa_tos, fa->fa_info, NLM_F_MULTI);
+               if (err < 0) {
                        cb->args[4] = i;
-                       return -1;
+                       return err;
                }
                i++;
        }
@@ -2025,10 +2024,13 @@ int fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
        t_key key = cb->args[3];
 
        while ((l = leaf_walk_rcu(&tp, key)) != NULL) {
-               if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+               int err;
+
+               err = fn_trie_dump_leaf(l, tb, skb, cb);
+               if (err < 0) {
                        cb->args[3] = key;
                        cb->args[2] = count;
-                       return -1;
+                       return err;
                }
 
                ++count;
index 3a02d52ed50ec54ce3f9f3eb07dc9f4133535a80..551de4d023a8edbf74835b43cb32d9173eedae36 100644 (file)
@@ -1980,6 +1980,20 @@ int ip_mr_input(struct sk_buff *skb)
        struct net *net = dev_net(skb->dev);
        int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
        struct mr_table *mrt;
+       struct net_device *dev;
+
+       /* skb->dev passed in is the loX master dev for vrfs.
+        * As there are no vifs associated with loopback devices,
+        * get the proper interface that does have a vif associated with it.
+        */
+       dev = skb->dev;
+       if (netif_is_l3_master(skb->dev)) {
+               dev = dev_get_by_index_rcu(net, IPCB(skb)->iif);
+               if (!dev) {
+                       kfree_skb(skb);
+                       return -ENODEV;
+               }
+       }
 
        /* Packet is looped back after forward, it should not be
         * forwarded second time, but still can be delivered locally.
@@ -2017,7 +2031,7 @@ int ip_mr_input(struct sk_buff *skb)
        /* already under rcu_read_lock() */
        cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr);
        if (!cache) {
-               int vif = ipmr_find_vif(mrt, skb->dev);
+               int vif = ipmr_find_vif(mrt, dev);
 
                if (vif >= 0)
                        cache = ipmr_cache_find_any(mrt, ip_hdr(skb)->daddr,
@@ -2037,7 +2051,7 @@ int ip_mr_input(struct sk_buff *skb)
                }
 
                read_lock(&mrt_lock);
-               vif = ipmr_find_vif(mrt, skb->dev);
+               vif = ipmr_find_vif(mrt, dev);
                if (vif >= 0) {
                        int err2 = ipmr_cache_unresolved(mrt, vif, skb);
                        read_unlock(&mrt_lock);
index 1e4c76d2b8278ba71d6cc2cf7ebfe483e241f76e..842b575f8fdddc41a41aa6f03fb9086cec7ee451 100644 (file)
@@ -2320,6 +2320,10 @@ int tcp_disconnect(struct sock *sk, int flags)
        tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
        inet_csk_delack_init(sk);
+       /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
+        * issue in __tcp_select_window()
+        */
+       icsk->icsk_ack.rcv_mss = TCP_MIN_MSS;
        tcp_init_send_head(sk);
        memset(&tp->rx_opt, 0, sizeof(tp->rx_opt));
        __sk_dst_reset(sk);
index 5a3ad09e2786fb41ad12681d09938c645b69866d..174d4376baa5374c11caecc0e0452fa938d63561 100644 (file)
@@ -1179,13 +1179,14 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
                 */
                if (pkt_len > mss) {
                        unsigned int new_len = (pkt_len / mss) * mss;
-                       if (!in_sack && new_len < pkt_len) {
+                       if (!in_sack && new_len < pkt_len)
                                new_len += mss;
-                               if (new_len >= skb->len)
-                                       return 0;
-                       }
                        pkt_len = new_len;
                }
+
+               if (pkt_len >= skb->len && !in_sack)
+                       return 0;
+
                err = tcp_fragment(sk, skb, pkt_len, mss, GFP_ATOMIC);
                if (err < 0)
                        return err;
@@ -3189,7 +3190,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
                        int delta;
 
                        /* Non-retransmitted hole got filled? That's reordering */
-                       if (reord < prior_fackets)
+                       if (reord < prior_fackets && reord <= tp->fackets_out)
                                tcp_update_reordering(sk, tp->fackets_out - reord, 0);
 
                        delta = tcp_is_fack(tp) ? pkts_acked :
index ea6e4cff9fafe99af23fd8ea666cd979d5af9104..1d6219bf2d6b48abaa73ad7f178049d95124cc90 100644 (file)
@@ -1612,7 +1612,7 @@ static void udp_v4_rehash(struct sock *sk)
        udp_lib_rehash(sk, new_hash);
 }
 
-int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int rc;
 
@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(udp_encap_enable);
  * Note that in the success and error cases, the skb is assumed to
  * have either been requeued or freed.
  */
-int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        struct udp_sock *up = udp_sk(sk);
        int is_udplite = IS_UDPLITE(sk);
index feb50a16398dfa856fd928fe823b4f6556d2caa1..a8cf8c6fb60ccf532fda1b109f902ead378acf22 100644 (file)
@@ -25,7 +25,6 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
                int flags, int *addr_len);
 int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size,
                 int flags);
-int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 void udp_destroy_sock(struct sock *sk);
 
 #ifdef CONFIG_PROC_FS
index 8d297a79b5680761b290aaa1bc947d05bcb60f3b..6a4fb1e629fb7609048156974ae2eb322cebddae 100644 (file)
@@ -1022,7 +1022,10 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
        INIT_HLIST_NODE(&ifa->addr_lst);
        ifa->scope = scope;
        ifa->prefix_len = pfxlen;
-       ifa->flags = flags | IFA_F_TENTATIVE;
+       ifa->flags = flags;
+       /* No need to add the TENTATIVE flag for addresses with NODAD */
+       if (!(flags & IFA_F_NODAD))
+               ifa->flags |= IFA_F_TENTATIVE;
        ifa->valid_lft = valid_lft;
        ifa->prefered_lft = prefered_lft;
        ifa->cstamp = ifa->tstamp = jiffies;
index 93e58a5e18374bee41f5a17f0c5911e381acb142..280268f1dd7b0972d7fadbcc9e28b043ceae423d 100644 (file)
@@ -63,7 +63,6 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
        const struct net_offload *ops;
        int proto;
        struct frag_hdr *fptr;
-       unsigned int unfrag_ip6hlen;
        unsigned int payload_len;
        u8 *prevhdr;
        int offset = 0;
@@ -116,8 +115,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
                skb->network_header = (u8 *)ipv6h - skb->head;
 
                if (udpfrag) {
-                       unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
-                       fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen);
+                       int err = ip6_find_1stfragopt(skb, &prevhdr);
+                       if (err < 0)
+                               return ERR_PTR(err);
+                       fptr = (struct frag_hdr *)((u8 *)ipv6h + err);
                        fptr->frag_off = htons(offset);
                        if (skb->next)
                                fptr->frag_off |= htons(IP6_MF);
index 58f6288e9ba53e6964b74d71dde7615ead695c06..bf8a58a1c32d83a9605844075da5815be23a6bf1 100644 (file)
@@ -597,7 +597,10 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
        int ptr, offset = 0, err = 0;
        u8 *prevhdr, nexthdr = 0;
 
-       hlen = ip6_find_1stfragopt(skb, &prevhdr);
+       err = ip6_find_1stfragopt(skb, &prevhdr);
+       if (err < 0)
+               goto fail;
+       hlen = err;
        nexthdr = *prevhdr;
 
        mtu = ip6_skb_dst_mtu(skb);
@@ -1463,6 +1466,11 @@ alloc_new_skb:
                         */
                        alloclen += sizeof(struct frag_hdr);
 
+                       copy = datalen - transhdrlen - fraggap;
+                       if (copy < 0) {
+                               err = -EINVAL;
+                               goto error;
+                       }
                        if (transhdrlen) {
                                skb = sock_alloc_send_skb(sk,
                                                alloclen + hh_len,
@@ -1512,13 +1520,9 @@ alloc_new_skb:
                                data += fraggap;
                                pskb_trim_unique(skb_prev, maxfraglen);
                        }
-                       copy = datalen - transhdrlen - fraggap;
-
-                       if (copy < 0) {
-                               err = -EINVAL;
-                               kfree_skb(skb);
-                               goto error;
-                       } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
+                       if (copy > 0 &&
+                           getfrag(from, data + transhdrlen, offset,
+                                   copy, fraggap, skb) < 0) {
                                err = -EFAULT;
                                kfree_skb(skb);
                                goto error;
index cd4252346a32d90e8e133bd985811b6241e4bcd7..e9065b8d3af852c6e9a7359667f68a5ad00bfe75 100644 (file)
@@ -79,14 +79,13 @@ EXPORT_SYMBOL(ipv6_select_ident);
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
        u16 offset = sizeof(struct ipv6hdr);
-       struct ipv6_opt_hdr *exthdr =
-                               (struct ipv6_opt_hdr *)(ipv6_hdr(skb) + 1);
        unsigned int packet_len = skb_tail_pointer(skb) -
                skb_network_header(skb);
        int found_rhdr = 0;
        *nexthdr = &ipv6_hdr(skb)->nexthdr;
 
-       while (offset + 1 <= packet_len) {
+       while (offset <= packet_len) {
+               struct ipv6_opt_hdr *exthdr;
 
                switch (**nexthdr) {
 
@@ -107,13 +106,16 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
                        return offset;
                }
 
-               offset += ipv6_optlen(exthdr);
-               *nexthdr = &exthdr->nexthdr;
+               if (offset + sizeof(struct ipv6_opt_hdr) > packet_len)
+                       return -EINVAL;
+
                exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
                                                 offset);
+               offset += ipv6_optlen(exthdr);
+               *nexthdr = &exthdr->nexthdr;
        }
 
-       return offset;
+       return -EINVAL;
 }
 EXPORT_SYMBOL(ip6_find_1stfragopt);
 
index 7a8237acd210bf58cdc98f085fcf7fed433c3f24..4f4310a36a0481e2bd068e39285011ff28377ea5 100644 (file)
@@ -1062,6 +1062,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
                newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
 #endif
 
+               newnp->ipv6_mc_list = NULL;
                newnp->ipv6_ac_list = NULL;
                newnp->ipv6_fl_list = NULL;
                newnp->pktoptions  = NULL;
@@ -1131,6 +1132,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
           First: no IPv4 options.
         */
        newinet->inet_opt = NULL;
+       newnp->ipv6_mc_list = NULL;
        newnp->ipv6_ac_list = NULL;
        newnp->ipv6_fl_list = NULL;
 
index 04862abfe4ec27d978adadd27735a9d19e3c4365..06ec39b796092ad5e8954c0cfd10e75205ffce54 100644 (file)
@@ -526,7 +526,7 @@ out:
        return;
 }
 
-int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        int rc;
 
@@ -569,7 +569,7 @@ void udpv6_encap_enable(void)
 }
 EXPORT_SYMBOL(udpv6_encap_enable);
 
-int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
        struct udp_sock *up = udp_sk(sk);
        int is_udplite = IS_UDPLITE(sk);
index e78bdc76dcc33ceda888fb323a530f774057edbb..f180b3d85e3147facb487720bb3d98722ae76a45 100644 (file)
@@ -26,7 +26,6 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
 int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
 int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
                  int flags, int *addr_len);
-int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
 void udpv6_destroy_sock(struct sock *sk);
 
 #ifdef CONFIG_PROC_FS
index ac858c480f2f272f37275cddfd9ffe889a91af97..a2267f80febbb6f31459097f27bd89d51d0f2b11 100644 (file)
@@ -29,6 +29,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        u8 frag_hdr_sz = sizeof(struct frag_hdr);
        __wsum csum;
        int tnl_hlen;
+       int err;
 
        mss = skb_shinfo(skb)->gso_size;
        if (unlikely(skb->len <= mss))
@@ -90,7 +91,10 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
                /* Find the unfragmentable header and shift it left by frag_hdr_sz
                 * bytes to insert fragment header.
                 */
-               unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+               err = ip6_find_1stfragopt(skb, &prevhdr);
+               if (err < 0)
+                       return ERR_PTR(err);
+               unfrag_ip6hlen = err;
                nexthdr = *prevhdr;
                *prevhdr = NEXTHDR_FRAGMENT;
                unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) +
index d2d7bdf1d5104b6e68284bbbb533c30f159844e2..ad99c1ceea6f42bf3e52500a4452f7f74e730be5 100644 (file)
@@ -849,10 +849,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
 {
        unsigned int verdict = NF_DROP;
 
-       if (IP_VS_FWD_METHOD(cp) != 0) {
-               pr_err("shouldn't reach here, because the box is on the "
-                      "half connection in the tun/dr module.\n");
-       }
+       if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+               goto ignore_cp;
 
        /* Ensure the checksum is correct */
        if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
@@ -886,6 +884,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
                ip_vs_notrack(skb);
        else
                ip_vs_update_conntrack(skb, cp, 0);
+
+ignore_cp:
        verdict = NF_ACCEPT;
 
 out:
@@ -1385,8 +1385,11 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
         */
        cp = pp->conn_out_get(ipvs, af, skb, &iph);
 
-       if (likely(cp))
+       if (likely(cp)) {
+               if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
+                       goto ignore_cp;
                return handle_response(af, skb, pd, cp, &iph, hooknum);
+       }
 
        /* Check for real-server-started requests */
        if (atomic_read(&ipvs->conn_out_counter)) {
@@ -1444,9 +1447,15 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
                        }
                }
        }
+
+out:
        IP_VS_DBG_PKT(12, af, pp, skb, iph.off,
                      "ip_vs_out: packet continues traversal as normal");
        return NF_ACCEPT;
+
+ignore_cp:
+       __ip_vs_conn_put(cp);
+       goto out;
 }
 
 /*
index 3a60efa7799b2e4569af35ce943c67fc354dc68a..7f6100ca63be6dd4f37c24852fd16b9a71b8a823 100644 (file)
@@ -174,6 +174,10 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)
 #endif
        if (h != NULL && !try_module_get(h->me))
                h = NULL;
+       if (h != NULL && !refcount_inc_not_zero(&h->refcnt)) {
+               module_put(h->me);
+               h = NULL;
+       }
 
        rcu_read_unlock();
 
@@ -181,6 +185,13 @@ nf_conntrack_helper_try_module_get(const char *name, u16 l3num, u8 protonum)
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_helper_try_module_get);
 
+void nf_conntrack_helper_put(struct nf_conntrack_helper *helper)
+{
+       refcount_dec(&helper->refcnt);
+       module_put(helper->me);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_helper_put);
+
 struct nf_conn_help *
 nf_ct_helper_ext_add(struct nf_conn *ct,
                     struct nf_conntrack_helper *helper, gfp_t gfp)
@@ -417,6 +428,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
                        }
                }
        }
+       refcount_set(&me->refcnt, 1);
        hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
        nf_ct_helper_count++;
 out:
index dcf561b5c97a47e627ee00649d756635db0e6fb3..9799a50bc604cc630494514cc80aa49edc2def0e 100644 (file)
@@ -45,6 +45,8 @@
 #include <net/netfilter/nf_conntrack_zones.h>
 #include <net/netfilter/nf_conntrack_timestamp.h>
 #include <net/netfilter/nf_conntrack_labels.h>
+#include <net/netfilter/nf_conntrack_seqadj.h>
+#include <net/netfilter/nf_conntrack_synproxy.h>
 #ifdef CONFIG_NF_NAT_NEEDED
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_l4proto.h>
@@ -1007,9 +1009,8 @@ static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = {
 
 static int
 ctnetlink_parse_tuple(const struct nlattr * const cda[],
-                     struct nf_conntrack_tuple *tuple,
-                     enum ctattr_type type, u_int8_t l3num,
-                     struct nf_conntrack_zone *zone)
+                     struct nf_conntrack_tuple *tuple, u32 type,
+                     u_int8_t l3num, struct nf_conntrack_zone *zone)
 {
        struct nlattr *tb[CTA_TUPLE_MAX+1];
        int err;
@@ -1828,6 +1829,8 @@ ctnetlink_create_conntrack(struct net *net,
        nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
        nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
        nf_ct_labels_ext_add(ct);
+       nfct_seqadj_ext_add(ct);
+       nfct_synproxy_ext_add(ct);
 
        /* we must add conntrack extensions before confirmation. */
        ct->status |= IPS_CONFIRMED;
@@ -2447,7 +2450,7 @@ static struct nfnl_ct_hook ctnetlink_glue_hook = {
 
 static int ctnetlink_exp_dump_tuple(struct sk_buff *skb,
                                    const struct nf_conntrack_tuple *tuple,
-                                   enum ctattr_expect type)
+                                   u32 type)
 {
        struct nlattr *nest_parms;
 
index b48d6b5aae8a87d4ea69cae0e025739ebe3f1658..ef0be325a0c6368bfe29ecda39db37dcb178a6d2 100644 (file)
@@ -409,6 +409,10 @@ nf_nat_setup_info(struct nf_conn *ct,
 {
        struct nf_conntrack_tuple curr_tuple, new_tuple;
 
+       /* Can't setup nat info for confirmed ct. */
+       if (nf_ct_is_confirmed(ct))
+               return NF_ACCEPT;
+
        NF_CT_ASSERT(maniptype == NF_NAT_MANIP_SRC ||
                     maniptype == NF_NAT_MANIP_DST);
        BUG_ON(nf_nat_initialized(ct, maniptype));
index 5592250297402fe6e272f3213efa7e02ab230485..da314be0c048720172bbd153cd2f730b486603ce 100644 (file)
@@ -3367,35 +3367,50 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
        return nf_tables_fill_setelem(args->skb, set, elem);
 }
 
+struct nft_set_dump_ctx {
+       const struct nft_set    *set;
+       struct nft_ctx          ctx;
+};
+
 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct nft_set_dump_ctx *dump_ctx = cb->data;
        struct net *net = sock_net(skb->sk);
-       u8 genmask = nft_genmask_cur(net);
+       struct nft_af_info *afi;
+       struct nft_table *table;
        struct nft_set *set;
        struct nft_set_dump_args args;
-       struct nft_ctx ctx;
-       struct nlattr *nla[NFTA_SET_ELEM_LIST_MAX + 1];
+       bool set_found = false;
        struct nfgenmsg *nfmsg;
        struct nlmsghdr *nlh;
        struct nlattr *nest;
        u32 portid, seq;
-       int event, err;
+       int event;
 
-       err = nlmsg_parse(cb->nlh, sizeof(struct nfgenmsg), nla,
-                         NFTA_SET_ELEM_LIST_MAX, nft_set_elem_list_policy,
-                         NULL);
-       if (err < 0)
-               return err;
+       rcu_read_lock();
+       list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
+               if (afi != dump_ctx->ctx.afi)
+                       continue;
 
-       err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
-                                        (void *)nla, genmask);
-       if (err < 0)
-               return err;
+               list_for_each_entry_rcu(table, &afi->tables, list) {
+                       if (table != dump_ctx->ctx.table)
+                               continue;
 
-       set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
-                                  genmask);
-       if (IS_ERR(set))
-               return PTR_ERR(set);
+                       list_for_each_entry_rcu(set, &table->sets, list) {
+                               if (set == dump_ctx->set) {
+                                       set_found = true;
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               break;
+       }
+
+       if (!set_found) {
+               rcu_read_unlock();
+               return -ENOENT;
+       }
 
        event  = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
        portid = NETLINK_CB(cb->skb).portid;
@@ -3407,11 +3422,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
                goto nla_put_failure;
 
        nfmsg = nlmsg_data(nlh);
-       nfmsg->nfgen_family = ctx.afi->family;
+       nfmsg->nfgen_family = afi->family;
        nfmsg->version      = NFNETLINK_V0;
-       nfmsg->res_id       = htons(ctx.net->nft.base_seq & 0xffff);
+       nfmsg->res_id       = htons(net->nft.base_seq & 0xffff);
 
-       if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name))
+       if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
                goto nla_put_failure;
        if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
                goto nla_put_failure;
@@ -3422,12 +3437,13 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
 
        args.cb                 = cb;
        args.skb                = skb;
-       args.iter.genmask       = nft_genmask_cur(ctx.net);
+       args.iter.genmask       = nft_genmask_cur(net);
        args.iter.skip          = cb->args[0];
        args.iter.count         = 0;
        args.iter.err           = 0;
        args.iter.fn            = nf_tables_dump_setelem;
-       set->ops->walk(&ctx, set, &args.iter);
+       set->ops->walk(&dump_ctx->ctx, set, &args.iter);
+       rcu_read_unlock();
 
        nla_nest_end(skb, nest);
        nlmsg_end(skb, nlh);
@@ -3441,9 +3457,16 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
        return skb->len;
 
 nla_put_failure:
+       rcu_read_unlock();
        return -ENOSPC;
 }
 
+static int nf_tables_dump_set_done(struct netlink_callback *cb)
+{
+       kfree(cb->data);
+       return 0;
+}
+
 static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
                                struct sk_buff *skb, const struct nlmsghdr *nlh,
                                const struct nlattr * const nla[])
@@ -3465,7 +3488,18 @@ static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
                struct netlink_dump_control c = {
                        .dump = nf_tables_dump_set,
+                       .done = nf_tables_dump_set_done,
                };
+               struct nft_set_dump_ctx *dump_ctx;
+
+               dump_ctx = kmalloc(sizeof(*dump_ctx), GFP_KERNEL);
+               if (!dump_ctx)
+                       return -ENOMEM;
+
+               dump_ctx->set = set;
+               dump_ctx->ctx = ctx;
+
+               c.data = dump_ctx;
                return netlink_dump_start(nlsk, skb, nlh, &c);
        }
        return -EOPNOTSUPP;
@@ -3593,9 +3627,9 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
 {
        struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
 
-       nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
+       nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
        if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
-               nft_data_uninit(nft_set_ext_data(ext), set->dtype);
+               nft_data_release(nft_set_ext_data(ext), set->dtype);
        if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
                nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
        if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
@@ -3604,6 +3638,18 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
 }
 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
 
+/* Only called from commit path, nft_set_elem_deactivate() already deals with
+ * the refcounting from the preparation phase.
+ */
+static void nf_tables_set_elem_destroy(const struct nft_set *set, void *elem)
+{
+       struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
+
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
+               nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
+       kfree(elem);
+}
+
 static int nft_setelem_parse_flags(const struct nft_set *set,
                                   const struct nlattr *attr, u32 *flags)
 {
@@ -3815,9 +3861,9 @@ err4:
        kfree(elem.priv);
 err3:
        if (nla[NFTA_SET_ELEM_DATA] != NULL)
-               nft_data_uninit(&data, d2.type);
+               nft_data_release(&data, d2.type);
 err2:
-       nft_data_uninit(&elem.key.val, d1.type);
+       nft_data_release(&elem.key.val, d1.type);
 err1:
        return err;
 }
@@ -3862,6 +3908,53 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
        return err;
 }
 
+/**
+ *     nft_data_hold - hold a nft_data item
+ *
+ *     @data: struct nft_data to release
+ *     @type: type of data
+ *
+ *     Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
+ *     NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
+ *     NFT_GOTO verdicts. This function must be called on active data objects
+ *     from the second phase of the commit protocol.
+ */
+static void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
+{
+       if (type == NFT_DATA_VERDICT) {
+               switch (data->verdict.code) {
+               case NFT_JUMP:
+               case NFT_GOTO:
+                       data->verdict.chain->use++;
+                       break;
+               }
+       }
+}
+
+static void nft_set_elem_activate(const struct net *net,
+                                 const struct nft_set *set,
+                                 struct nft_set_elem *elem)
+{
+       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
+               nft_data_hold(nft_set_ext_data(ext), set->dtype);
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
+               (*nft_set_ext_obj(ext))->use++;
+}
+
+static void nft_set_elem_deactivate(const struct net *net,
+                                   const struct nft_set *set,
+                                   struct nft_set_elem *elem)
+{
+       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
+               nft_data_release(nft_set_ext_data(ext), set->dtype);
+       if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
+               (*nft_set_ext_obj(ext))->use--;
+}
+
 static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
                           const struct nlattr *attr)
 {
@@ -3927,6 +4020,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
        kfree(elem.priv);
        elem.priv = priv;
 
+       nft_set_elem_deactivate(ctx->net, set, &elem);
+
        nft_trans_elem(trans) = elem;
        list_add_tail(&trans->list, &ctx->net->nft.commit_list);
        return 0;
@@ -3936,7 +4031,7 @@ err4:
 err3:
        kfree(elem.priv);
 err2:
-       nft_data_uninit(&elem.key.val, desc.type);
+       nft_data_release(&elem.key.val, desc.type);
 err1:
        return err;
 }
@@ -4743,8 +4838,8 @@ static void nf_tables_commit_release(struct nft_trans *trans)
                nft_set_destroy(nft_trans_set(trans));
                break;
        case NFT_MSG_DELSETELEM:
-               nft_set_elem_destroy(nft_trans_elem_set(trans),
-                                    nft_trans_elem(trans).priv, true);
+               nf_tables_set_elem_destroy(nft_trans_elem_set(trans),
+                                          nft_trans_elem(trans).priv);
                break;
        case NFT_MSG_DELOBJ:
                nft_obj_destroy(nft_trans_obj(trans));
@@ -4979,6 +5074,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
                case NFT_MSG_DELSETELEM:
                        te = (struct nft_trans_elem *)trans->data;
 
+                       nft_set_elem_activate(net, te->set, &te->elem);
                        te->set->ops->activate(net, te->set, &te->elem);
                        te->set->ndeact--;
 
@@ -5464,7 +5560,7 @@ int nft_data_init(const struct nft_ctx *ctx,
 EXPORT_SYMBOL_GPL(nft_data_init);
 
 /**
- *     nft_data_uninit - release a nft_data item
+ *     nft_data_release - release a nft_data item
  *
  *     @data: struct nft_data to release
  *     @type: type of data
@@ -5472,7 +5568,7 @@ EXPORT_SYMBOL_GPL(nft_data_init);
  *     Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
  *     all others need to be released by calling this function.
  */
-void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
+void nft_data_release(const struct nft_data *data, enum nft_data_types type)
 {
        if (type < NFT_DATA_VERDICT)
                return;
@@ -5483,7 +5579,7 @@ void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
                WARN_ON(1);
        }
 }
-EXPORT_SYMBOL_GPL(nft_data_uninit);
+EXPORT_SYMBOL_GPL(nft_data_release);
 
 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
                  enum nft_data_types type, unsigned int len)
index 950bf6eadc6578516ac92b50427fe682cba3976d..be678a323598c3237a2cae09e4e3ed4bdea46614 100644 (file)
@@ -686,6 +686,7 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
                tuple_set = true;
        }
 
+       ret = -ENOENT;
        list_for_each_entry_safe(nlcth, n, &nfnl_cthelper_list, list) {
                cur = &nlcth->helper;
                j++;
@@ -699,16 +700,20 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
                     tuple.dst.protonum != cur->tuple.dst.protonum))
                        continue;
 
-               found = true;
-               nf_conntrack_helper_unregister(cur);
-               kfree(cur->expect_policy);
+               if (refcount_dec_if_one(&cur->refcnt)) {
+                       found = true;
+                       nf_conntrack_helper_unregister(cur);
+                       kfree(cur->expect_policy);
 
-               list_del(&nlcth->list);
-               kfree(nlcth);
+                       list_del(&nlcth->list);
+                       kfree(nlcth);
+               } else {
+                       ret = -EBUSY;
+               }
        }
 
        /* Make sure we return success if we flush and there is no helpers */
-       return (found || j == 0) ? 0 : -ENOENT;
+       return (found || j == 0) ? 0 : ret;
 }
 
 static const struct nla_policy nfnl_cthelper_policy[NFCTH_MAX+1] = {
index 877d9acd91ef5c616c43d00f265facbfe4c2d334..fff8073e2a5692c14037a77c5d8151cf0c1bbcb0 100644 (file)
@@ -83,17 +83,26 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
                            tb[NFTA_BITWISE_MASK]);
        if (err < 0)
                return err;
-       if (d1.len != priv->len)
-               return -EINVAL;
+       if (d1.len != priv->len) {
+               err = -EINVAL;
+               goto err1;
+       }
 
        err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
                            tb[NFTA_BITWISE_XOR]);
        if (err < 0)
-               return err;
-       if (d2.len != priv->len)
-               return -EINVAL;
+               goto err1;
+       if (d2.len != priv->len) {
+               err = -EINVAL;
+               goto err2;
+       }
 
        return 0;
+err2:
+       nft_data_release(&priv->xor, d2.type);
+err1:
+       nft_data_release(&priv->mask, d1.type);
+       return err;
 }
 
 static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
index 2b96effeadc1bc708a1f16e89342c8d39c4c4da7..c2945eb3397c8991ae05ea84abb2ba15591cbefb 100644 (file)
@@ -201,10 +201,18 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
        if (err < 0)
                return ERR_PTR(err);
 
+       if (desc.type != NFT_DATA_VALUE) {
+               err = -EINVAL;
+               goto err1;
+       }
+
        if (desc.len <= sizeof(u32) && op == NFT_CMP_EQ)
                return &nft_cmp_fast_ops;
-       else
-               return &nft_cmp_ops;
+
+       return &nft_cmp_ops;
+err1:
+       nft_data_release(&data, desc.type);
+       return ERR_PTR(-EINVAL);
 }
 
 struct nft_expr_type nft_cmp_type __read_mostly = {
index a34ceb38fc55681962daad2c323f0011a5fe683d..1678e9e75e8ee7d22301d6083ddeb04dd39ab385 100644 (file)
@@ -826,9 +826,9 @@ static void nft_ct_helper_obj_destroy(struct nft_object *obj)
        struct nft_ct_helper_obj *priv = nft_obj_data(obj);
 
        if (priv->helper4)
-               module_put(priv->helper4->me);
+               nf_conntrack_helper_put(priv->helper4);
        if (priv->helper6)
-               module_put(priv->helper6->me);
+               nf_conntrack_helper_put(priv->helper6);
 }
 
 static void nft_ct_helper_obj_eval(struct nft_object *obj,
index 728baf88295aab3d4f0e1272d551672ae5a2fb13..4717d77969271c324087ed7677df636b414e54ad 100644 (file)
@@ -65,7 +65,7 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
        return 0;
 
 err1:
-       nft_data_uninit(&priv->data, desc.type);
+       nft_data_release(&priv->data, desc.type);
        return err;
 }
 
@@ -73,7 +73,8 @@ static void nft_immediate_destroy(const struct nft_ctx *ctx,
                                  const struct nft_expr *expr)
 {
        const struct nft_immediate_expr *priv = nft_expr_priv(expr);
-       return nft_data_uninit(&priv->data, nft_dreg_to_type(priv->dreg));
+
+       return nft_data_release(&priv->data, nft_dreg_to_type(priv->dreg));
 }
 
 static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr)
index 9edc74eedc1021e836bc767defc02fac1a63333f..cedb96c3619fa991395602dff1363314d3de13ea 100644 (file)
@@ -102,9 +102,9 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr
        priv->len = desc_from.len;
        return 0;
 err2:
-       nft_data_uninit(&priv->data_to, desc_to.type);
+       nft_data_release(&priv->data_to, desc_to.type);
 err1:
-       nft_data_uninit(&priv->data_from, desc_from.type);
+       nft_data_release(&priv->data_from, desc_from.type);
        return err;
 }
 
index 8ec086b6b56b742485e34511b38a77af848d9f99..3d3a6df4ce70ea0950a4f07cab75b3c54680e09a 100644 (file)
@@ -222,7 +222,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, struct nft_set *set,
        struct nft_set_elem elem;
        int err;
 
-       err = rhashtable_walk_init(&priv->ht, &hti, GFP_KERNEL);
+       err = rhashtable_walk_init(&priv->ht, &hti, GFP_ATOMIC);
        iter->err = err;
        if (err)
                return;
index 8876b7da6884c210393d1988032cbb5bd7018507..1770c1d9b37fc14be9d9d8cf4721d21c745826ad 100644 (file)
@@ -283,28 +283,30 @@ static int xt_obj_to_user(u16 __user *psize, u16 size,
                       &U->u.user.revision, K->u.kernel.TYPE->revision)
 
 int xt_data_to_user(void __user *dst, const void *src,
-                   int usersize, int size)
+                   int usersize, int size, int aligned_size)
 {
        usersize = usersize ? : size;
        if (copy_to_user(dst, src, usersize))
                return -EFAULT;
-       if (usersize != size && clear_user(dst + usersize, size - usersize))
+       if (usersize != aligned_size &&
+           clear_user(dst + usersize, aligned_size - usersize))
                return -EFAULT;
 
        return 0;
 }
 EXPORT_SYMBOL_GPL(xt_data_to_user);
 
-#define XT_DATA_TO_USER(U, K, TYPE, C_SIZE)                            \
+#define XT_DATA_TO_USER(U, K, TYPE)                                    \
        xt_data_to_user(U->data, K->data,                               \
                        K->u.kernel.TYPE->usersize,                     \
-                       C_SIZE ? : K->u.kernel.TYPE->TYPE##size)
+                       K->u.kernel.TYPE->TYPE##size,                   \
+                       XT_ALIGN(K->u.kernel.TYPE->TYPE##size))
 
 int xt_match_to_user(const struct xt_entry_match *m,
                     struct xt_entry_match __user *u)
 {
        return XT_OBJ_TO_USER(u, m, match, 0) ||
-              XT_DATA_TO_USER(u, m, match, 0);
+              XT_DATA_TO_USER(u, m, match);
 }
 EXPORT_SYMBOL_GPL(xt_match_to_user);
 
@@ -312,7 +314,7 @@ int xt_target_to_user(const struct xt_entry_target *t,
                      struct xt_entry_target __user *u)
 {
        return XT_OBJ_TO_USER(u, t, target, 0) ||
-              XT_DATA_TO_USER(u, t, target, 0);
+              XT_DATA_TO_USER(u, t, target);
 }
 EXPORT_SYMBOL_GPL(xt_target_to_user);
 
@@ -611,6 +613,12 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
 
+#define COMPAT_XT_DATA_TO_USER(U, K, TYPE, C_SIZE)                     \
+       xt_data_to_user(U->data, K->data,                               \
+                       K->u.kernel.TYPE->usersize,                     \
+                       C_SIZE,                                         \
+                       COMPAT_XT_ALIGN(C_SIZE))
+
 int xt_compat_match_to_user(const struct xt_entry_match *m,
                            void __user **dstptr, unsigned int *size)
 {
@@ -626,7 +634,7 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
                if (match->compat_to_user((void __user *)cm->data, m->data))
                        return -EFAULT;
        } else {
-               if (XT_DATA_TO_USER(cm, m, match, msize - sizeof(*cm)))
+               if (COMPAT_XT_DATA_TO_USER(cm, m, match, msize - sizeof(*cm)))
                        return -EFAULT;
        }
 
@@ -972,7 +980,7 @@ int xt_compat_target_to_user(const struct xt_entry_target *t,
                if (target->compat_to_user((void __user *)ct->data, t->data))
                        return -EFAULT;
        } else {
-               if (XT_DATA_TO_USER(ct, t, target, tsize - sizeof(*ct)))
+               if (COMPAT_XT_DATA_TO_USER(ct, t, target, tsize - sizeof(*ct)))
                        return -EFAULT;
        }
 
index bb7ad82dcd5603e810db8fba35f81d3f2c03a2b7..623ef37de886fa22fd508a1261f0c1934f767e5f 100644 (file)
@@ -96,7 +96,7 @@ xt_ct_set_helper(struct nf_conn *ct, const char *helper_name,
 
        help = nf_ct_helper_ext_add(ct, helper, GFP_KERNEL);
        if (help == NULL) {
-               module_put(helper->me);
+               nf_conntrack_helper_put(helper);
                return -ENOMEM;
        }
 
@@ -263,7 +263,7 @@ out:
 err4:
        help = nfct_help(ct);
        if (help)
-               module_put(help->helper->me);
+               nf_conntrack_helper_put(help->helper);
 err3:
        nf_ct_tmpl_free(ct);
 err2:
@@ -346,7 +346,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par,
        if (ct) {
                help = nfct_help(ct);
                if (help)
-                       module_put(help->helper->me);
+                       nf_conntrack_helper_put(help->helper);
 
                nf_ct_netns_put(par->net, par->family);
 
index bf602e33c40af4896240c9cc0566fa10126cf662..08679ebb3068298a58a081926c6a7dd5a2a73d17 100644 (file)
@@ -1123,7 +1123,7 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
 
        help = nf_ct_helper_ext_add(info->ct, helper, GFP_KERNEL);
        if (!help) {
-               module_put(helper->me);
+               nf_conntrack_helper_put(helper);
                return -ENOMEM;
        }
 
@@ -1584,7 +1584,7 @@ void ovs_ct_free_action(const struct nlattr *a)
 static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
 {
        if (ct_info->helper)
-               module_put(ct_info->helper->me);
+               nf_conntrack_helper_put(ct_info->helper);
        if (ct_info->ct)
                nf_ct_tmpl_free(ct_info->ct);
 }
index f4001763134da35ed5f0f04bc2836015bb15a4af..e3eeed19cc7a130e80e24a3d67776a5b5a3c2698 100644 (file)
@@ -2658,13 +2658,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
        }
 
-       sockc.tsflags = po->sk.sk_tsflags;
-       if (msg->msg_controllen) {
-               err = sock_cmsg_send(&po->sk, msg, &sockc);
-               if (unlikely(err))
-                       goto out;
-       }
-
        err = -ENXIO;
        if (unlikely(dev == NULL))
                goto out;
@@ -2672,6 +2665,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
        if (unlikely(!(dev->flags & IFF_UP)))
                goto out_put;
 
+       sockc.tsflags = po->sk.sk_tsflags;
+       if (msg->msg_controllen) {
+               err = sock_cmsg_send(&po->sk, msg, &sockc);
+               if (unlikely(err))
+                       goto out_put;
+       }
+
        if (po->sk.sk_socket->type == SOCK_RAW)
                reserve = dev->hard_header_len;
        size_max = po->tx_ring.frame_size
index dee469fed9671d518dbeddd6bd48d96cc9158675..51859b8edd7eff3845ca3d5b5b0d900583736d4a 100644 (file)
@@ -203,7 +203,6 @@ static int mall_change(struct net *net, struct sk_buff *in_skb,
 
        *arg = (unsigned long) head;
        rcu_assign_pointer(tp->root, new);
-       call_rcu(&head->rcu, mall_destroy_rcu);
        return 0;
 
 err_replace_hw_filter:
index bbe57d57b67fd498692bd41db49147511f1bb091..e88342fde1bc409aed6a3c86e7a628030eaac66f 100644 (file)
@@ -1831,6 +1831,12 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
        if (!qdisc_dev(root))
                return 0;
 
+       if (tcm->tcm_parent) {
+               q = qdisc_match_from_root(root, TC_H_MAJ(tcm->tcm_parent));
+               if (q && tc_dump_tclass_qdisc(q, skb, tcm, cb, t_p, s_t) < 0)
+                       return -1;
+               return 0;
+       }
        hash_for_each(qdisc_dev(root)->qdisc_hash, b, q, hash) {
                if (tc_dump_tclass_qdisc(q, skb, tcm, cb, t_p, s_t) < 0)
                        return -1;
index 961ee59f696a0b0a8b6c2bade0031a073dff53ad..f5b45b8b8b16e6965d24cd79b150828a608c2121 100644 (file)
@@ -240,12 +240,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
        struct sctp_bind_addr *bp;
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct sctp_sockaddr_entry *laddr;
-       union sctp_addr *baddr = NULL;
        union sctp_addr *daddr = &t->ipaddr;
        union sctp_addr dst_saddr;
        struct in6_addr *final_p, final;
        __u8 matchlen = 0;
-       __u8 bmatchlen;
        sctp_scope_t scope;
 
        memset(fl6, 0, sizeof(struct flowi6));
@@ -312,23 +310,37 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
         */
        rcu_read_lock();
        list_for_each_entry_rcu(laddr, &bp->address_list, list) {
-               if (!laddr->valid)
+               struct dst_entry *bdst;
+               __u8 bmatchlen;
+
+               if (!laddr->valid ||
+                   laddr->state != SCTP_ADDR_SRC ||
+                   laddr->a.sa.sa_family != AF_INET6 ||
+                   scope > sctp_scope(&laddr->a))
                        continue;
-               if ((laddr->state == SCTP_ADDR_SRC) &&
-                   (laddr->a.sa.sa_family == AF_INET6) &&
-                   (scope <= sctp_scope(&laddr->a))) {
-                       bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
-                       if (!baddr || (matchlen < bmatchlen)) {
-                               baddr = &laddr->a;
-                               matchlen = bmatchlen;
-                       }
-               }
-       }
-       if (baddr) {
-               fl6->saddr = baddr->v6.sin6_addr;
-               fl6->fl6_sport = baddr->v6.sin6_port;
+
+               fl6->saddr = laddr->a.v6.sin6_addr;
+               fl6->fl6_sport = laddr->a.v6.sin6_port;
                final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
-               dst = ip6_dst_lookup_flow(sk, fl6, final_p);
+               bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
+
+               if (!IS_ERR(bdst) &&
+                   ipv6_chk_addr(dev_net(bdst->dev),
+                                 &laddr->a.v6.sin6_addr, bdst->dev, 1)) {
+                       if (!IS_ERR_OR_NULL(dst))
+                               dst_release(dst);
+                       dst = bdst;
+                       break;
+               }
+
+               bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
+               if (matchlen > bmatchlen)
+                       continue;
+
+               if (!IS_ERR_OR_NULL(dst))
+                       dst_release(dst);
+               dst = bdst;
+               matchlen = bmatchlen;
        }
        rcu_read_unlock();
 
@@ -665,6 +677,9 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
        newnp = inet6_sk(newsk);
 
        memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+       newnp->ipv6_mc_list = NULL;
+       newnp->ipv6_ac_list = NULL;
+       newnp->ipv6_fl_list = NULL;
 
        rcu_read_lock();
        opt = rcu_dereference(np->opt);
index c717ef0896aa2accaee05e3cf4c10d066c61eeb3..33954852f3f89b3bd05595a159e5c2ed56d074ad 100644 (file)
@@ -8,6 +8,10 @@ config SMC
          The Linux implementation of the SMC-R solution is designed as
          a separate socket family SMC.
 
+         Warning: SMC will expose all memory for remote reads and writes
+         once a connection is established.  Don't enable this option except
+         for tightly controlled lab environment.
+
          Select this option if you want to run SMC socket applications
 
 config SMC_DIAG
index e41f594a1e1d0c3d47706e4c80f9de587f953c9b..03ec058d18df642ef7e219000a62e51bc6c0e6fe 100644 (file)
@@ -204,7 +204,7 @@ int smc_clc_send_confirm(struct smc_sock *smc)
        memcpy(&cclc.lcl.mac, &link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
        hton24(cclc.qpn, link->roce_qp->qp_num);
        cclc.rmb_rkey =
-               htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
+               htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
        cclc.conn_idx = 1; /* for now: 1 RMB = 1 RMBE */
        cclc.rmbe_alert_token = htonl(conn->alert_token_local);
        cclc.qp_mtu = min(link->path_mtu, link->peer_mtu);
@@ -256,7 +256,7 @@ int smc_clc_send_accept(struct smc_sock *new_smc, int srv_first_contact)
        memcpy(&aclc.lcl.mac, link->smcibdev->mac[link->ibport - 1], ETH_ALEN);
        hton24(aclc.qpn, link->roce_qp->qp_num);
        aclc.rmb_rkey =
-               htonl(conn->rmb_desc->mr_rx[SMC_SINGLE_LINK]->rkey);
+               htonl(conn->rmb_desc->rkey[SMC_SINGLE_LINK]);
        aclc.conn_idx = 1;                      /* as long as 1 RMB = 1 RMBE */
        aclc.rmbe_alert_token = htonl(conn->alert_token_local);
        aclc.qp_mtu = link->path_mtu;
index 65020e93ff210bb7f5db079399984c55e54c80f1..3ac09a629ea1a4c38c6bc21d996a69611c1633b7 100644 (file)
@@ -613,19 +613,8 @@ int smc_rmb_create(struct smc_sock *smc)
                        rmb_desc = NULL;
                        continue; /* if mapping failed, try smaller one */
                }
-               rc = smc_ib_get_memory_region(lgr->lnk[SMC_SINGLE_LINK].roce_pd,
-                                             IB_ACCESS_REMOTE_WRITE |
-                                             IB_ACCESS_LOCAL_WRITE,
-                                            &rmb_desc->mr_rx[SMC_SINGLE_LINK]);
-               if (rc) {
-                       smc_ib_buf_unmap(lgr->lnk[SMC_SINGLE_LINK].smcibdev,
-                                        tmp_bufsize, rmb_desc,
-                                        DMA_FROM_DEVICE);
-                       kfree(rmb_desc->cpu_addr);
-                       kfree(rmb_desc);
-                       rmb_desc = NULL;
-                       continue;
-               }
+               rmb_desc->rkey[SMC_SINGLE_LINK] =
+                       lgr->lnk[SMC_SINGLE_LINK].roce_pd->unsafe_global_rkey;
                rmb_desc->used = 1;
                write_lock_bh(&lgr->rmbs_lock);
                list_add(&rmb_desc->list,
@@ -668,6 +657,7 @@ int smc_rmb_rtoken_handling(struct smc_connection *conn,
 
        for (i = 0; i < SMC_RMBS_PER_LGR_MAX; i++) {
                if ((lgr->rtokens[i][SMC_SINGLE_LINK].rkey == rkey) &&
+                   (lgr->rtokens[i][SMC_SINGLE_LINK].dma_addr == dma_addr) &&
                    test_bit(i, lgr->rtokens_used_mask)) {
                        conn->rtoken_idx = i;
                        return 0;
index 27eb38056a27fb07e3ce72afbacaffaf4ae55f73..b013cb43a327ea81cd8bc9e4a5ffff733f87f6a7 100644 (file)
@@ -93,7 +93,7 @@ struct smc_buf_desc {
        u64                     dma_addr[SMC_LINKS_PER_LGR_MAX];
                                                /* mapped address of buffer */
        void                    *cpu_addr;      /* virtual address of buffer */
-       struct ib_mr            *mr_rx[SMC_LINKS_PER_LGR_MAX];
+       u32                     rkey[SMC_LINKS_PER_LGR_MAX];
                                                /* for rmb only:
                                                 * rkey provided to peer
                                                 */
index cb69ab977cd73963fef1fe27b1407e58a6e7cadd..b31715505a358cd4e73d1af6c58a49ef7ef8ecbe 100644 (file)
@@ -37,24 +37,6 @@ u8 local_systemid[SMC_SYSTEMID_LEN] = SMC_LOCAL_SYSTEMID_RESET;      /* unique system
                                                                 * identifier
                                                                 */
 
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
-                            struct ib_mr **mr)
-{
-       int rc;
-
-       if (*mr)
-               return 0; /* already done */
-
-       /* obtain unique key -
-        * next invocation of get_dma_mr returns a different key!
-        */
-       *mr = pd->device->get_dma_mr(pd, access_flags);
-       rc = PTR_ERR_OR_ZERO(*mr);
-       if (IS_ERR(*mr))
-               *mr = NULL;
-       return rc;
-}
-
 static int smc_ib_modify_qp_init(struct smc_link *lnk)
 {
        struct ib_qp_attr qp_attr;
@@ -210,7 +192,8 @@ int smc_ib_create_protection_domain(struct smc_link *lnk)
 {
        int rc;
 
-       lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev, 0);
+       lnk->roce_pd = ib_alloc_pd(lnk->smcibdev->ibdev,
+                                  IB_PD_UNSAFE_GLOBAL_RKEY);
        rc = PTR_ERR_OR_ZERO(lnk->roce_pd);
        if (IS_ERR(lnk->roce_pd))
                lnk->roce_pd = NULL;
index 7e1f0e24d17790f526aa50d07ff5e5d6596b6f3c..b567152a526d48c86110a9574833e8610684af4b 100644 (file)
@@ -61,8 +61,6 @@ void smc_ib_dealloc_protection_domain(struct smc_link *lnk);
 int smc_ib_create_protection_domain(struct smc_link *lnk);
 void smc_ib_destroy_queue_pair(struct smc_link *lnk);
 int smc_ib_create_queue_pair(struct smc_link *lnk);
-int smc_ib_get_memory_region(struct ib_pd *pd, int access_flags,
-                            struct ib_mr **mr);
 int smc_ib_ready_link(struct smc_link *lnk);
 int smc_ib_modify_qp_rts(struct smc_link *lnk);
 int smc_ib_modify_qp_reset(struct smc_link *lnk);
index 0d4f2f455a7c91a1d7ea2b0fd9c8d121e6da98af..1b92b72e812f942fc9826d8542f29bf1bd7c26c5 100644 (file)
@@ -362,25 +362,25 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout)
        return 0;
 }
 
-#define tipc_wait_for_cond(sock_, timeout_, condition_)                        \
-({                                                                     \
-       int rc_ = 0;                                                    \
-       int done_ = 0;                                                  \
-                                                                       \
-       while (!(condition_) && !done_) {                               \
-               struct sock *sk_ = sock->sk;                            \
-               DEFINE_WAIT_FUNC(wait_, woken_wake_function);           \
-                                                                       \
-               rc_ = tipc_sk_sock_err(sock_, timeout_);                \
-               if (rc_)                                                \
-                       break;                                          \
-               prepare_to_wait(sk_sleep(sk_), &wait_,                  \
-                               TASK_INTERRUPTIBLE);                    \
-               done_ = sk_wait_event(sk_, timeout_,                    \
-                                     (condition_), &wait_);            \
-               remove_wait_queue(sk_sleep(sk_), &wait_);               \
-       }                                                               \
-       rc_;                                                            \
+#define tipc_wait_for_cond(sock_, timeo_, condition_)                         \
+({                                                                             \
+       struct sock *sk_;                                                      \
+       int rc_;                                                               \
+                                                                              \
+       while ((rc_ = !(condition_))) {                                        \
+               DEFINE_WAIT_FUNC(wait_, woken_wake_function);                  \
+               sk_ = (sock_)->sk;                                             \
+               rc_ = tipc_sk_sock_err((sock_), timeo_);                       \
+               if (rc_)                                                       \
+                       break;                                                 \
+               prepare_to_wait(sk_sleep(sk_), &wait_, TASK_INTERRUPTIBLE);    \
+               release_sock(sk_);                                             \
+               *(timeo_) = wait_woken(&wait_, TASK_INTERRUPTIBLE, *(timeo_)); \
+               sched_annotate_sleep();                                        \
+               lock_sock(sk_);                                                \
+               remove_wait_queue(sk_sleep(sk_), &wait_);                      \
+       }                                                                      \
+       rc_;                                                                   \
 })
 
 /**
index 6f7f6757ceefb500551fafbf40c462835c4baf88..dfc8c51e4d74ec378a338ab9bb2560b3811f393b 100644 (file)
@@ -1540,8 +1540,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
        long timeout;
        int err;
        struct vsock_transport_send_notify_data send_data;
-
-       DEFINE_WAIT(wait);
+       DEFINE_WAIT_FUNC(wait, woken_wake_function);
 
        sk = sock->sk;
        vsk = vsock_sk(sk);
@@ -1584,11 +1583,10 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
        if (err < 0)
                goto out;
 
-
        while (total_written < len) {
                ssize_t written;
 
-               prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+               add_wait_queue(sk_sleep(sk), &wait);
                while (vsock_stream_has_space(vsk) == 0 &&
                       sk->sk_err == 0 &&
                       !(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1597,33 +1595,30 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
                        /* Don't wait for non-blocking sockets. */
                        if (timeout == 0) {
                                err = -EAGAIN;
-                               finish_wait(sk_sleep(sk), &wait);
+                               remove_wait_queue(sk_sleep(sk), &wait);
                                goto out_err;
                        }
 
                        err = transport->notify_send_pre_block(vsk, &send_data);
                        if (err < 0) {
-                               finish_wait(sk_sleep(sk), &wait);
+                               remove_wait_queue(sk_sleep(sk), &wait);
                                goto out_err;
                        }
 
                        release_sock(sk);
-                       timeout = schedule_timeout(timeout);
+                       timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
                        lock_sock(sk);
                        if (signal_pending(current)) {
                                err = sock_intr_errno(timeout);
-                               finish_wait(sk_sleep(sk), &wait);
+                               remove_wait_queue(sk_sleep(sk), &wait);
                                goto out_err;
                        } else if (timeout == 0) {
                                err = -EAGAIN;
-                               finish_wait(sk_sleep(sk), &wait);
+                               remove_wait_queue(sk_sleep(sk), &wait);
                                goto out_err;
                        }
-
-                       prepare_to_wait(sk_sleep(sk), &wait,
-                                       TASK_INTERRUPTIBLE);
                }
-               finish_wait(sk_sleep(sk), &wait);
+               remove_wait_queue(sk_sleep(sk), &wait);
 
                /* These checks occur both as part of and after the loop
                 * conditional since we need to check before and after
index 8b911c29860e79f21b0ac8e1d3a80ed373fd537e..5a1a98df3499841172f47b71418f95d9558158d0 100644 (file)
@@ -1791,32 +1791,40 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
 
 static int __init x25_init(void)
 {
-       int rc = proto_register(&x25_proto, 0);
+       int rc;
 
-       if (rc != 0)
+       rc = proto_register(&x25_proto, 0);
+       if (rc)
                goto out;
 
        rc = sock_register(&x25_family_ops);
-       if (rc != 0)
+       if (rc)
                goto out_proto;
 
        dev_add_pack(&x25_packet_type);
 
        rc = register_netdevice_notifier(&x25_dev_notifier);
-       if (rc != 0)
+       if (rc)
                goto out_sock;
 
-       pr_info("Linux Version 0.2\n");
+       rc = x25_register_sysctl();
+       if (rc)
+               goto out_dev;
 
-       x25_register_sysctl();
        rc = x25_proc_init();
-       if (rc != 0)
-               goto out_dev;
+       if (rc)
+               goto out_sysctl;
+
+       pr_info("Linux Version 0.2\n");
+
 out:
        return rc;
+out_sysctl:
+       x25_unregister_sysctl();
 out_dev:
        unregister_netdevice_notifier(&x25_dev_notifier);
 out_sock:
+       dev_remove_pack(&x25_packet_type);
        sock_unregister(AF_X25);
 out_proto:
        proto_unregister(&x25_proto);
index a06dfe143c675039b57cdc5a83164228730d3e5e..ba078c85f0a1533ffbbadef1ab5789399dd1528a 100644 (file)
@@ -73,9 +73,12 @@ static struct ctl_table x25_table[] = {
        { },
 };
 
-void __init x25_register_sysctl(void)
+int __init x25_register_sysctl(void)
 {
        x25_table_header = register_net_sysctl(&init_net, "net/x25", x25_table);
+       if (!x25_table_header)
+               return -ENOMEM;
+       return 0;
 }
 
 void x25_unregister_sysctl(void)
index b08ab4e889293c30f64b717065e6860603063f7c..9d751e209f313ca8f20a07e6d578cfb98c23defd 100644 (file)
@@ -306,7 +306,9 @@ int main(int argc, char *argv[])
        prog_attach_iptables(argv[2]);
        if (cfg_test_traffic) {
                if (signal(SIGINT, finish) == SIG_ERR)
-                       error(1, errno, "register handler failed");
+                       error(1, errno, "register SIGINT handler failed");
+               if (signal(SIGTERM, finish) == SIG_ERR)
+                       error(1, errno, "register SIGTERM handler failed");
                while (!test_finish) {
                        print_table();
                        printf("\n");
index 9cce2a66bd664c40668b3c8ca0dd12bd148bb21b..512f87a5fd20e08d0b97893b17e20e971425830e 100644 (file)
@@ -100,6 +100,7 @@ int main(int argc, char **argv)
        setrlimit(RLIMIT_MEMLOCK, &r);
 
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        if (load_kallsyms()) {
                printf("failed to process /proc/kallsyms\n");
index be59d7dcbdde3664c573a78d6d27adee03234a16..4ed690b907ff844961499d492350746065e423fb 100644 (file)
@@ -180,6 +180,7 @@ int main(int argc, char **argv)
                return 1;
        }
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        /* do sampling */
        printf("Sampling at %d Hertz for %d seconds. Ctrl-C also ends.\n",
index 0c5561d193a487f2257ccece359530b97b06a170..fa4336423da569f31fc432b9adc61f0835bb3f69 100644 (file)
@@ -192,6 +192,7 @@ int main(int argc, char **argv)
        setrlimit(RLIMIT_MEMLOCK, &r);
 
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        if (load_kallsyms()) {
                printf("failed to process /proc/kallsyms\n");
index 7fee0f1ba9a313baf2d233b3bf705994c183755e..7321a3f253c991f88e96f2a53e6ffa3e7c5f1719 100644 (file)
@@ -127,6 +127,7 @@ int main(int ac, char **argv)
        }
 
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        /* start 'ping' in the background to have some kfree_skb events */
        f = popen("ping -c5 localhost", "r");
index 378850c70eb81afdbc5283611573f89ea4d8923e..2431c0321b712ce54d15414836b148d483a8a632 100644 (file)
@@ -62,13 +62,14 @@ static void usage(const char *prog)
        fprintf(stderr,
                "usage: %s [OPTS] IFINDEX\n\n"
                "OPTS:\n"
-               "    -S    use skb-mode\n",
+               "    -S    use skb-mode\n"
+               "    -N    enforce native mode\n",
                prog);
 }
 
 int main(int argc, char **argv)
 {
-       const char *optstr = "S";
+       const char *optstr = "SN";
        char filename[256];
        int opt;
 
@@ -77,6 +78,9 @@ int main(int argc, char **argv)
                case 'S':
                        xdp_flags |= XDP_FLAGS_SKB_MODE;
                        break;
+               case 'N':
+                       xdp_flags |= XDP_FLAGS_DRV_MODE;
+                       break;
                default:
                        usage(basename(argv[0]));
                        return 1;
@@ -102,6 +106,7 @@ int main(int argc, char **argv)
        }
 
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
                printf("link set xdp fd failed\n");
index 92b8bde9337c8cec6128e73d23d307b628ba5a38..715cd12eaca5c0729d11e0918e564db9e2fa980f 100644 (file)
@@ -79,6 +79,8 @@ static void usage(const char *cmd)
        printf("    -m <dest-MAC> Used in sending the IP Tunneled pkt\n");
        printf("    -T <stop-after-X-seconds> Default: 0 (forever)\n");
        printf("    -P <IP-Protocol> Default is TCP\n");
+       printf("    -S use skb-mode\n");
+       printf("    -N enforce native mode\n");
        printf("    -h Display this help\n");
 }
 
@@ -138,7 +140,7 @@ int main(int argc, char **argv)
 {
        unsigned char opt_flags[256] = {};
        unsigned int kill_after_s = 0;
-       const char *optstr = "i:a:p:s:d:m:T:P:Sh";
+       const char *optstr = "i:a:p:s:d:m:T:P:SNh";
        int min_port = 0, max_port = 0;
        struct iptnl_info tnl = {};
        struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
@@ -206,6 +208,9 @@ int main(int argc, char **argv)
                case 'S':
                        xdp_flags |= XDP_FLAGS_SKB_MODE;
                        break;
+               case 'N':
+                       xdp_flags |= XDP_FLAGS_DRV_MODE;
+                       break;
                default:
                        usage(argv[0]);
                        return 1;
@@ -239,6 +244,7 @@ int main(int argc, char **argv)
        }
 
        signal(SIGINT, int_exit);
+       signal(SIGTERM, int_exit);
 
        while (min_port <= max_port) {
                vip.dport = htons(min_port++);
index 6ba97a1f9c5a26304abdf0f043211efe6c273ffc..ce753a408c56823dbd1c4b5d4fb5cfe88e7054c4 100644 (file)
@@ -8,6 +8,29 @@
 #
 # ==========================================================================
 
+PHONY := __headers
+__headers:
+
+include scripts/Kbuild.include
+
+srcdir        := $(srctree)/$(obj)
+subdirs       := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+# caller may set destination dir (when installing to asm/)
+_dst          := $(if $(dst),$(dst),$(obj))
+
+# Recursion
+__headers: $(subdirs)
+
+.PHONY: $(subdirs)
+$(subdirs):
+       $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
+
+# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi.
+# We have only sub-directories there.
+skip-inst := $(if $(filter %/uapi,$(obj)),1)
+
+ifeq ($(skip-inst),)
+
 # generated header directory
 gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
 
@@ -15,21 +38,14 @@ gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
 kbuild-file := $(srctree)/$(obj)/Kbuild
 -include $(kbuild-file)
 
-# called may set destination dir (when installing to asm/)
-_dst := $(if $(dst),$(dst),$(obj))
-
 old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
 ifneq ($(wildcard $(old-kbuild-file)),)
 include $(old-kbuild-file)
 endif
 
-include scripts/Kbuild.include
-
 installdir    := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
 
-srcdir        := $(srctree)/$(obj)
 gendir        := $(objtree)/$(gen)
-subdirs       := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
 header-files  := $(notdir $(wildcard $(srcdir)/*.h))
 header-files  += $(notdir $(wildcard $(srcdir)/*.agh))
 header-files  := $(filter-out $(no-export-headers), $(header-files))
@@ -88,11 +104,9 @@ quiet_cmd_check = CHECK   $(printdir) ($(words $(all-files)) files)
                   $(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
                  touch $@
 
-PHONY += __headersinst __headerscheck
-
 ifndef HDRCHECK
 # Rules for installing headers
-__headersinst: $(subdirs) $(install-file)
+__headers: $(install-file)
        @:
 
 targets += $(install-file)
@@ -104,7 +118,7 @@ $(install-file): scripts/headers_install.sh \
        $(call if_changed,install)
 
 else
-__headerscheck: $(subdirs) $(check-file)
+__headers: $(check-file)
        @:
 
 targets += $(check-file)
@@ -113,11 +127,6 @@ $(check-file): scripts/headers_check.pl $(output-files) FORCE
 
 endif
 
-# Recursion
-.PHONY: $(subdirs)
-$(subdirs):
-       $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
-
 targets := $(wildcard $(sort $(targets)))
 cmd_files := $(wildcard \
              $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
@@ -126,6 +135,8 @@ ifneq ($(cmd_files),)
        include $(cmd_files)
 endif
 
+endif # skip-inst
+
 .PHONY: $(PHONY)
 PHONY += FORCE
 FORCE: ;
index 6dc1eda13b8e841d8cdbdd2b0ec664df84607801..58c05e5d9870b6c18a72da7dc44ff3112994946d 100644 (file)
@@ -175,7 +175,7 @@ ld_flags       = $(LDFLAGS) $(ldflags-y)
 
 dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
                 -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
-                -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
+                -I$(srctree)/scripts/dtc/include-prefixes               \
                 -I$(srctree)/drivers/of/testcase-data                   \
                 -undef -D__DTS__
 
index 5adfc8f52b4fd23e0533cb2084cc893753dd9abf..4b72b530c84f1f4b4e98d8342d9d62fefe8d34d6 100644 (file)
@@ -873,7 +873,7 @@ static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct no
        while (size--)
                reg = (reg << 32) | fdt32_to_cpu(*(cells++));
 
-       snprintf(unit_addr, sizeof(unit_addr), "%lx", reg);
+       snprintf(unit_addr, sizeof(unit_addr), "%zx", reg);
        if (!streq(unitname, unit_addr))
                FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
                     node->fullpath, unit_addr);
diff --git a/scripts/dtc/include-prefixes/arc b/scripts/dtc/include-prefixes/arc
new file mode 120000 (symlink)
index 0000000..5d21b5a
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/arc/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/arm b/scripts/dtc/include-prefixes/arm
new file mode 120000 (symlink)
index 0000000..eb14d45
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/arm/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/arm64 b/scripts/dtc/include-prefixes/arm64
new file mode 120000 (symlink)
index 0000000..275c42c
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/arm64/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/c6x b/scripts/dtc/include-prefixes/c6x
new file mode 120000 (symlink)
index 0000000..49ded4c
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/c6x/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/cris b/scripts/dtc/include-prefixes/cris
new file mode 120000 (symlink)
index 0000000..736d998
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/cris/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/dt-bindings b/scripts/dtc/include-prefixes/dt-bindings
new file mode 120000 (symlink)
index 0000000..04fdbb3
--- /dev/null
@@ -0,0 +1 @@
+../../../include/dt-bindings
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/h8300 b/scripts/dtc/include-prefixes/h8300
new file mode 120000 (symlink)
index 0000000..3bdaa33
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/h8300/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/metag b/scripts/dtc/include-prefixes/metag
new file mode 120000 (symlink)
index 0000000..87a3c84
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/metag/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/microblaze b/scripts/dtc/include-prefixes/microblaze
new file mode 120000 (symlink)
index 0000000..d983033
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/microblaze/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/mips b/scripts/dtc/include-prefixes/mips
new file mode 120000 (symlink)
index 0000000..ae8d494
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/mips/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/nios2 b/scripts/dtc/include-prefixes/nios2
new file mode 120000 (symlink)
index 0000000..5177233
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/nios2/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/openrisc b/scripts/dtc/include-prefixes/openrisc
new file mode 120000 (symlink)
index 0000000..71c3bc7
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/openrisc/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/powerpc b/scripts/dtc/include-prefixes/powerpc
new file mode 120000 (symlink)
index 0000000..7cd6ec1
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/powerpc/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/sh b/scripts/dtc/include-prefixes/sh
new file mode 120000 (symlink)
index 0000000..67d3780
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/sh/boot/dts
\ No newline at end of file
diff --git a/scripts/dtc/include-prefixes/xtensa b/scripts/dtc/include-prefixes/xtensa
new file mode 120000 (symlink)
index 0000000..d1eaf6e
--- /dev/null
@@ -0,0 +1 @@
+../../../arch/xtensa/boot/dts
\ No newline at end of file
index 664b7fe206d65457cf3e7b1486a05b7e92493cb8..b11d3920b9a521b95142481106d420ac75643b26 100644 (file)
@@ -1809,10 +1809,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
        pdata->notify_pending = false;
        spin_unlock_irq(&pdata->lpe_audio_slock);
 
-       /* runtime PM isn't enabled as default, since it won't save much on
-        * BYT/CHT devices; user who want the runtime PM should adjust the
-        * power/ontrol and power/autosuspend_delay_ms sysfs entries instead
-        */
        pm_runtime_use_autosuspend(&pdev->dev);
        pm_runtime_mark_last_busy(&pdev->dev);
        pm_runtime_set_active(&pdev->dev);
index ebc6dceddb58c00e4253e4fc3b37eda7a17b62be..7598361ef1f10898ea73d944ae0b0c02c4725d99 100644 (file)
@@ -29,6 +29,7 @@ int main(void)
        attr.log_size = 0;
        attr.log_level = 0;
        attr.kern_version = 0;
+       attr.prog_flags = 0;
 
        /*
         * Test existence of __NR_bpf and BPF_PROG_LOAD.
index e553529929f683c4c39ae336d10c6f670e589b54..94dfa9def355f7f52805bba5ade3a32c304f989a 100644 (file)
@@ -132,6 +132,13 @@ enum bpf_attach_type {
  */
 #define BPF_F_ALLOW_OVERRIDE   (1U << 0)
 
+/* If BPF_F_STRICT_ALIGNMENT is used in BPF_PROG_LOAD command, the
+ * verifier will perform strict alignment checking as if the kernel
+ * has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set,
+ * and NET_IP_ALIGN defined to 2.
+ */
+#define BPF_F_STRICT_ALIGNMENT (1U << 0)
+
 #define BPF_PSEUDO_MAP_FD      1
 
 /* flags for BPF_MAP_UPDATE_ELEM command */
@@ -177,6 +184,7 @@ union bpf_attr {
                __u32           log_size;       /* size of user buffer */
                __aligned_u64   log_buf;        /* user supplied buffer */
                __u32           kern_version;   /* checked when prog_type=kprobe */
+               __u32           prog_flags;
        };
 
        struct { /* anonymous struct used by BPF_OBJ_* commands */
@@ -481,8 +489,7 @@ union bpf_attr {
  * u32 bpf_get_socket_uid(skb)
  *     Get the owner uid of the socket stored inside sk_buff.
  *     @skb: pointer to skb
- *     Return: uid of the socket owner on success or 0 if the socket pointer
- *     inside sk_buff is NULL
+ *     Return: uid of the socket owner on success or overflowuid if failed.
  */
 #define __BPF_FUNC_MAPPER(FN)          \
        FN(unspec),                     \
index 4fe444b8092e2d6dc8aea6b7ce8349a64e439c44..6e178987af8e3f45d63da349e38c39b4e4cd6d84 100644 (file)
@@ -117,6 +117,28 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
        return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
 }
 
+int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
+                      size_t insns_cnt, int strict_alignment,
+                      const char *license, __u32 kern_version,
+                      char *log_buf, size_t log_buf_sz)
+{
+       union bpf_attr attr;
+
+       bzero(&attr, sizeof(attr));
+       attr.prog_type = type;
+       attr.insn_cnt = (__u32)insns_cnt;
+       attr.insns = ptr_to_u64(insns);
+       attr.license = ptr_to_u64(license);
+       attr.log_buf = ptr_to_u64(log_buf);
+       attr.log_size = log_buf_sz;
+       attr.log_level = 2;
+       log_buf[0] = 0;
+       attr.kern_version = kern_version;
+       attr.prog_flags = strict_alignment ? BPF_F_STRICT_ALIGNMENT : 0;
+
+       return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
+
 int bpf_map_update_elem(int fd, const void *key, const void *value,
                        __u64 flags)
 {
index edb4daeff7a52c44f6bc366c265a7f5a3aadfc10..972bd8333eb72e982420abeac9f8ceff5a4ed1a3 100644 (file)
@@ -35,6 +35,10 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
                     size_t insns_cnt, const char *license,
                     __u32 kern_version, char *log_buf,
                     size_t log_buf_sz);
+int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
+                      size_t insns_cnt, int strict_alignment,
+                      const char *license, __u32 kern_version,
+                      char *log_buf, size_t log_buf_sz);
 
 int bpf_map_update_elem(int fd, const void *key, const void *value,
                        __u64 flags);
diff --git a/tools/power/acpi/.gitignore b/tools/power/acpi/.gitignore
new file mode 100644 (file)
index 0000000..cba3d99
--- /dev/null
@@ -0,0 +1,4 @@
+acpidbg
+acpidump
+ec
+include
index 91edd056623789fb5585bd774b6d98eb5dba1cc2..f389b02d43a004e90aed9acd68148875af3beba2 100644 (file)
@@ -11,7 +11,8 @@ endif
 CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
 LDLIBS += -lcap -lelf
 
-TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs
+TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
+       test_align
 
 TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o
 
@@ -34,6 +35,7 @@ $(BPFOBJ): force
 CLANG ?= clang
 
 %.o: %.c
-       $(CLANG) -I. -I../../../include/uapi -I../../../../samples/bpf/ \
+       $(CLANG) -I. -I./include/uapi -I../../../include/uapi \
+               -I../../../../samples/bpf/ \
                -Wno-compare-distinct-pointer-types \
                -O2 -target bpf -c $< -o $@
diff --git a/tools/testing/selftests/bpf/include/uapi/linux/types.h b/tools/testing/selftests/bpf/include/uapi/linux/types.h
new file mode 100644 (file)
index 0000000..5184184
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _UAPI_LINUX_TYPES_H
+#define _UAPI_LINUX_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+/* copied from linux:include/uapi/linux/types.h */
+#define __bitwise
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+#define __aligned_u64 __u64 __attribute__((aligned(8)))
+#define __aligned_be64 __be64 __attribute__((aligned(8)))
+#define __aligned_le64 __le64 __attribute__((aligned(8)))
+
+#endif /* _UAPI_LINUX_TYPES_H */
diff --git a/tools/testing/selftests/bpf/test_align.c b/tools/testing/selftests/bpf/test_align.c
new file mode 100644 (file)
index 0000000..9644d4e
--- /dev/null
@@ -0,0 +1,453 @@
+#include <asm/types.h>
+#include <linux/types.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <linux/unistd.h>
+#include <linux/filter.h>
+#include <linux/bpf_perf_event.h>
+#include <linux/bpf.h>
+
+#include <bpf/bpf.h>
+
+#include "../../../include/linux/filter.h"
+
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+#define MAX_INSNS      512
+#define MAX_MATCHES    16
+
+struct bpf_align_test {
+       const char *descr;
+       struct bpf_insn insns[MAX_INSNS];
+       enum {
+               UNDEF,
+               ACCEPT,
+               REJECT
+       } result;
+       enum bpf_prog_type prog_type;
+       const char *matches[MAX_MATCHES];
+};
+
+static struct bpf_align_test tests[] = {
+       {
+               .descr = "mov",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_3, 2),
+                       BPF_MOV64_IMM(BPF_REG_3, 4),
+                       BPF_MOV64_IMM(BPF_REG_3, 8),
+                       BPF_MOV64_IMM(BPF_REG_3, 16),
+                       BPF_MOV64_IMM(BPF_REG_3, 32),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "1: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+                       "2: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+                       "3: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+                       "4: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+                       "5: R1=ctx R3=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
+               },
+       },
+       {
+               .descr = "shift",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_3, 4),
+                       BPF_MOV64_IMM(BPF_REG_4, 32),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "1: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
+                       "2: R1=ctx R3=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+                       "3: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+                       "4: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+                       "5: R1=ctx R3=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+                       "6: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R10=fp",
+                       "7: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm32,min_value=32,max_value=32,min_align=32 R10=fp",
+                       "8: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm16,min_value=16,max_value=16,min_align=16 R10=fp",
+                       "9: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+                       "10: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+                       "11: R1=ctx R3=imm1,min_value=1,max_value=1,min_align=1 R4=imm2,min_value=2,max_value=2,min_align=2 R10=fp",
+               },
+       },
+       {
+               .descr = "addsub",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_3, 4),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 4),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 2),
+                       BPF_MOV64_IMM(BPF_REG_4, 8),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 2),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "1: R1=ctx R3=imm4,min_value=4,max_value=4,min_align=4 R10=fp",
+                       "2: R1=ctx R3=imm8,min_value=8,max_value=8,min_align=4 R10=fp",
+                       "3: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R10=fp",
+                       "4: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm8,min_value=8,max_value=8,min_align=8 R10=fp",
+                       "5: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm12,min_value=12,max_value=12,min_align=4 R10=fp",
+                       "6: R1=ctx R3=imm10,min_value=10,max_value=10,min_align=2 R4=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
+               },
+       },
+       {
+               .descr = "mul",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_3, 7),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 2),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_3, 4),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "1: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
+                       "2: R1=ctx R3=imm7,min_value=7,max_value=7,min_align=1 R10=fp",
+                       "3: R1=ctx R3=imm14,min_value=14,max_value=14,min_align=2 R10=fp",
+                       "4: R1=ctx R3=imm56,min_value=56,max_value=56,min_align=4 R10=fp",
+               },
+       },
+
+#define PREP_PKT_POINTERS \
+       BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, \
+                   offsetof(struct __sk_buff, data)), \
+       BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, \
+                   offsetof(struct __sk_buff, data_end))
+
+#define LOAD_UNKNOWN(DST_REG) \
+       PREP_PKT_POINTERS, \
+       BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), \
+       BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 8), \
+       BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_0, 1), \
+       BPF_EXIT_INSN(), \
+       BPF_LDX_MEM(BPF_B, DST_REG, BPF_REG_2, 0)
+
+       {
+               .descr = "unknown shift",
+               .insns = {
+                       LOAD_UNKNOWN(BPF_REG_3),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_3, 1),
+                       LOAD_UNKNOWN(BPF_REG_4),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_4, 5),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_ALU64_IMM(BPF_RSH, BPF_REG_4, 1),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
+                       "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv55,min_align=2 R10=fp",
+                       "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv54,min_align=4 R10=fp",
+                       "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv53,min_align=8 R10=fp",
+                       "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv52,min_align=16 R10=fp",
+                       "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv56 R10=fp",
+                       "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv51,min_align=32 R10=fp",
+                       "20: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv52,min_align=16 R10=fp",
+                       "21: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv53,min_align=8 R10=fp",
+                       "22: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv54,min_align=4 R10=fp",
+                       "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv55,min_align=2 R10=fp",
+               },
+       },
+       {
+               .descr = "unknown mul",
+               .insns = {
+                       LOAD_UNKNOWN(BPF_REG_3),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 1),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 4),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_3),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 8),
+                       BPF_ALU64_IMM(BPF_MUL, BPF_REG_4, 2),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "7: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R10=fp",
+                       "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+                       "9: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv55,min_align=1 R10=fp",
+                       "10: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+                       "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv54,min_align=2 R10=fp",
+                       "12: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+                       "13: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv53,min_align=4 R10=fp",
+                       "14: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv56 R10=fp",
+                       "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv52,min_align=8 R10=fp",
+                       "16: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=inv56 R4=inv50,min_align=8 R10=fp"
+               },
+       },
+       {
+               .descr = "packet const offset",
+               .insns = {
+                       PREP_PKT_POINTERS,
+                       BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+
+                       /* Skip over ethernet header.  */
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+                       BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+                       BPF_EXIT_INSN(),
+
+                       BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 0),
+                       BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 1),
+                       BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 2),
+                       BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_5, 3),
+                       BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 0),
+                       BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_5, 2),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       "4: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=0,r=0) R10=fp",
+                       "5: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R5=pkt(id=0,off=14,r=0) R10=fp",
+                       "6: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=0) R3=pkt_end R4=pkt(id=0,off=14,r=0) R5=pkt(id=0,off=14,r=0) R10=fp",
+                       "10: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv56 R5=pkt(id=0,off=14,r=18) R10=fp",
+                       "14: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
+                       "15: R0=imm0,min_value=0,max_value=0,min_align=2147483648 R1=ctx R2=pkt(id=0,off=0,r=18) R3=pkt_end R4=inv48 R5=pkt(id=0,off=14,r=18) R10=fp",
+               },
+       },
+       {
+               .descr = "packet variable offset",
+               .insns = {
+                       LOAD_UNKNOWN(BPF_REG_6),
+                       BPF_ALU64_IMM(BPF_LSH, BPF_REG_6, 2),
+
+                       /* First, add a constant to the R5 packet pointer,
+                        * then a variable with a known alignment.
+                        */
+                       BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+                       BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+                       BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+                       /* Now, test in the other direction.  Adding first
+                        * the variable offset to R5, then the constant.
+                        */
+                       BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+                       BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+                       BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+                       /* Test multiple accumulations of unknown values
+                        * into a packet pointer.
+                        */
+                       BPF_MOV64_REG(BPF_REG_5, BPF_REG_2),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 14),
+                       BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, 4),
+                       BPF_ALU64_REG(BPF_ADD, BPF_REG_5, BPF_REG_6),
+                       BPF_MOV64_REG(BPF_REG_4, BPF_REG_5),
+                       BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 4),
+                       BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_4, 1),
+                       BPF_EXIT_INSN(),
+                       BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_5, 0),
+
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SCHED_CLS,
+               .matches = {
+                       /* Calculated offset in R6 has unknown value, but known
+                        * alignment of 4.
+                        */
+                       "8: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R6=inv54,min_align=4 R10=fp",
+
+                       /* Offset is added to packet pointer R5, resulting in known
+                        * auxiliary alignment and offset.
+                        */
+                       "11: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R5=pkt(id=1,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+                       /* At the time the word size load is performed from R5,
+                        * it's total offset is NET_IP_ALIGN + reg->off (0) +
+                        * reg->aux_off (14) which is 16.  Then the variable
+                        * offset is considered using reg->aux_off_align which
+                        * is 4 and meets the load's requirements.
+                        */
+                       "15: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=1,off=4,r=4),aux_off=14,aux_off_align=4 R5=pkt(id=1,off=0,r=4),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+
+                       /* Variable offset is added to R5 packet pointer,
+                        * resulting in auxiliary alignment of 4.
+                        */
+                       "18: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=0,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+                       /* Constant offset is added to R5, resulting in
+                        * reg->off of 14.
+                        */
+                       "19: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off=14,aux_off_align=4 R5=pkt(id=2,off=14,r=0),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+                       /* At the time the word size load is performed from R5,
+                        * it's total offset is NET_IP_ALIGN + reg->off (14) which
+                        * is 16.  Then the variable offset is considered using
+                        * reg->aux_off_align which is 4 and meets the load's
+                        * requirements.
+                        */
+                       "23: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=2,off=18,r=18),aux_off_align=4 R5=pkt(id=2,off=14,r=18),aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+
+                       /* Constant offset is added to R5 packet pointer,
+                        * resulting in reg->off value of 14.
+                        */
+                       "26: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=0,off=14,r=8) R6=inv54,min_align=4 R10=fp",
+                       /* Variable offset is added to R5, resulting in an
+                        * auxiliary offset of 14, and an auxiliary alignment of 4.
+                        */
+                       "27: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=0,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+                       /* Constant is added to R5 again, setting reg->off to 4. */
+                       "28: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=3,off=4,r=0),aux_off=14,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+                       /* And once more we add a variable, which causes an accumulation
+                        * of reg->off into reg->aux_off_align, with resulting value of
+                        * 18.  The auxiliary alignment stays at 4.
+                        */
+                       "29: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=inv,aux_off_align=4 R5=pkt(id=4,off=0,r=0),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+                       /* At the time the word size load is performed from R5,
+                        * it's total offset is NET_IP_ALIGN + reg->off (0) +
+                        * reg->aux_off (18) which is 20.  Then the variable offset
+                        * is considered using reg->aux_off_align which is 4 and meets
+                        * the load's requirements.
+                        */
+                       "33: R0=pkt(id=0,off=8,r=8) R1=ctx R2=pkt(id=0,off=0,r=8) R3=pkt_end R4=pkt(id=4,off=4,r=4),aux_off=18,aux_off_align=4 R5=pkt(id=4,off=0,r=4),aux_off=18,aux_off_align=4 R6=inv54,min_align=4 R10=fp",
+               },
+       },
+};
+
+static int probe_filter_length(const struct bpf_insn *fp)
+{
+       int len;
+
+       for (len = MAX_INSNS - 1; len > 0; --len)
+               if (fp[len].code != 0 || fp[len].imm != 0)
+                       break;
+       return len + 1;
+}
+
+static char bpf_vlog[32768];
+
+static int do_test_single(struct bpf_align_test *test)
+{
+       struct bpf_insn *prog = test->insns;
+       int prog_type = test->prog_type;
+       int prog_len, i;
+       int fd_prog;
+       int ret;
+
+       prog_len = probe_filter_length(prog);
+       fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
+                                    prog, prog_len, 1, "GPL", 0,
+                                    bpf_vlog, sizeof(bpf_vlog));
+       if (fd_prog < 0) {
+               printf("Failed to load program.\n");
+               printf("%s", bpf_vlog);
+               ret = 1;
+       } else {
+               ret = 0;
+               for (i = 0; i < MAX_MATCHES; i++) {
+                       const char *t, *m = test->matches[i];
+
+                       if (!m)
+                               break;
+                       t = strstr(bpf_vlog, m);
+                       if (!t) {
+                               printf("Failed to find match: %s\n", m);
+                               ret = 1;
+                               printf("%s", bpf_vlog);
+                               break;
+                       }
+               }
+               close(fd_prog);
+       }
+       return ret;
+}
+
+static int do_test(unsigned int from, unsigned int to)
+{
+       int all_pass = 0;
+       int all_fail = 0;
+       unsigned int i;
+
+       for (i = from; i < to; i++) {
+               struct bpf_align_test *test = &tests[i];
+               int fail;
+
+               printf("Test %3d: %s ... ",
+                      i, test->descr);
+               fail = do_test_single(test);
+               if (fail) {
+                       all_fail++;
+                       printf("FAIL\n");
+               } else {
+                       all_pass++;
+                       printf("PASS\n");
+               }
+       }
+       printf("Results: %d pass %d fail\n",
+              all_pass, all_fail);
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       unsigned int from = 0, to = ARRAY_SIZE(tests);
+
+       if (argc == 3) {
+               unsigned int l = atoi(argv[argc - 2]);
+               unsigned int u = atoi(argv[argc - 1]);
+
+               if (l < to && u < to) {
+                       from = l;
+                       to   = u + 1;
+               }
+       } else if (argc == 2) {
+               unsigned int t = atoi(argv[argc - 1]);
+
+               if (t < to) {
+                       from = t;
+                       to   = t + 1;
+               }
+       }
+       return do_test(from, to);
+}
index 39387bb7e08ca79be1ebd94452c0c126abd2316c..6e11ba11709e5cfcba232be08e706622515cdcef 100644 (file)
@@ -5,6 +5,7 @@
  * License as published by the Free Software Foundation.
  */
 #include <stddef.h>
+#include <string.h>
 #include <linux/bpf.h>
 #include <linux/if_ether.h>
 #include <linux/if_packet.h>
index 32e6211e1c6e81f44028f9d3b0f78fb8f8c0eb0d..717581145cfcf9dbf8ec129c81c26ce81d4d9ddf 100755 (executable)
@@ -58,7 +58,7 @@ parse_opts() { # opts
     ;;
     --verbose|-v|-vv)
       VERBOSE=$((VERBOSE + 1))
-      [ $1 == '-vv' ] && VERBOSE=$((VERBOSE + 1))
+      [ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1))
       shift 1
     ;;
     --debug|-d)
index 07bb3e5930b459b6ad52765ff92fb0fa416e603d..aa31368851c952e2f6e9dc78dd4a4915a36450fc 100644 (file)
@@ -48,7 +48,7 @@ test_event_enabled() {
     e=`cat $EVENT_ENABLE`
     if [ "$e" != $val ]; then
        echo "Expected $val but found $e"
-       exit -1
+       exit 1
     fi
 }
 
index 9aec6fcb7729ff0e7ec600ae91b80a24236b7bf6..f2019b37370d310cd845b6a42101d77cad77bc6b 100644 (file)
@@ -34,10 +34,10 @@ reset_ftrace_filter() { # reset all triggers in set_ftrace_filter
     echo > set_ftrace_filter
     grep -v '^#' set_ftrace_filter | while read t; do
        tr=`echo $t | cut -d: -f2`
-       if [ "$tr" == "" ]; then
+       if [ "$tr" = "" ]; then
            continue
        fi
-       if [ $tr == "enable_event" -o $tr == "disable_event" ]; then
+       if [ $tr = "enable_event" -o $tr = "disable_event" ]; then
            tr=`echo $t | cut -d: -f1-4`
            limit=`echo $t | cut -d: -f5`
        else
index 4c5a061a5b4e6d522396714de21f64b871e23ab4..c73db7863adbf41b51bd6b88ca79881801d59943 100644 (file)
@@ -75,9 +75,13 @@ rmdir foo
 if [ -d foo ]; then
         fail "foo still exists"
 fi
-exit 0
-
 
+mkdir foo
+echo "schedule:enable_event:sched:sched_switch" > foo/set_ftrace_filter
+rmdir foo
+if [ -d foo ]; then
+        fail "foo still exists"
+fi
 
 
 instance_slam() {
index 427621792229e68c7fcdaff89f28782bda14c1da..2f1f7b013293491b2845f68fa03dbc591c8d5412 100644 (file)
@@ -11,3 +11,4 @@ tm-signal-context-chk-fpu
 tm-signal-context-chk-gpr
 tm-signal-context-chk-vmx
 tm-signal-context-chk-vsx
+tm-vmx-unavail
index 5576ee6a51f21bb32a0ede4337d9da049e37fd42..958c11c14acd017a6c3afe79f02d9c6e8fad2240 100644 (file)
@@ -2,7 +2,8 @@ SIGNAL_CONTEXT_CHK_TESTS := tm-signal-context-chk-gpr tm-signal-context-chk-fpu
        tm-signal-context-chk-vmx tm-signal-context-chk-vsx
 
 TEST_GEN_PROGS := tm-resched-dscr tm-syscall tm-signal-msr-resv tm-signal-stack \
-       tm-vmxcopy tm-fork tm-tar tm-tmspr $(SIGNAL_CONTEXT_CHK_TESTS)
+       tm-vmxcopy tm-fork tm-tar tm-tmspr tm-vmx-unavail \
+       $(SIGNAL_CONTEXT_CHK_TESTS)
 
 include ../../lib.mk
 
@@ -13,6 +14,7 @@ CFLAGS += -mhtm
 $(OUTPUT)/tm-syscall: tm-syscall-asm.S
 $(OUTPUT)/tm-syscall: CFLAGS += -I../../../../../usr/include
 $(OUTPUT)/tm-tmspr: CFLAGS += -pthread
+$(OUTPUT)/tm-vmx-unavail: CFLAGS += -pthread -m64
 
 SIGNAL_CONTEXT_CHK_TESTS := $(patsubst %,$(OUTPUT)/%,$(SIGNAL_CONTEXT_CHK_TESTS))
 $(SIGNAL_CONTEXT_CHK_TESTS): tm-signal.S
diff --git a/tools/testing/selftests/powerpc/tm/tm-vmx-unavail.c b/tools/testing/selftests/powerpc/tm/tm-vmx-unavail.c
new file mode 100644 (file)
index 0000000..137185b
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2017, Michael Neuling, IBM Corp.
+ * Licensed under GPLv2.
+ * Original: Breno Leitao <brenohl@br.ibm.com> &
+ *           Gustavo Bueno Romero <gromero@br.ibm.com>
+ * Edited: Michael Neuling
+ *
+ * Force VMX unavailable during a transaction and see if it corrupts
+ * the checkpointed VMX register state after the abort.
+ */
+
+#include <inttypes.h>
+#include <htmintrin.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "tm.h"
+#include "utils.h"
+
+int passed;
+
+void *worker(void *unused)
+{
+       __int128 vmx0;
+       uint64_t texasr;
+
+       asm goto (
+               "li       3, 1;"  /* Stick non-zero value in VMX0 */
+               "std      3, 0(%[vmx0_ptr]);"
+               "lvx      0, 0, %[vmx0_ptr];"
+
+               /* Wait here a bit so we get scheduled out 255 times */
+               "lis      3, 0x3fff;"
+               "1: ;"
+               "addi     3, 3, -1;"
+               "cmpdi    3, 0;"
+               "bne      1b;"
+
+               /* Kernel will hopefully turn VMX off now */
+
+               "tbegin. ;"
+               "beq      failure;"
+
+               /* Cause VMX unavail. Any VMX instruction */
+               "vaddcuw  0,0,0;"
+
+               "tend. ;"
+               "b        %l[success];"
+
+               /* Check VMX0 sanity after abort */
+               "failure: ;"
+               "lvx       1,  0, %[vmx0_ptr];"
+               "vcmpequb. 2,  0, 1;"
+               "bc        4, 24, %l[value_mismatch];"
+               "b        %l[value_match];"
+               :
+               : [vmx0_ptr] "r"(&vmx0)
+               : "r3"
+               : success, value_match, value_mismatch
+               );
+
+       /* HTM aborted and VMX0 is corrupted */
+value_mismatch:
+       texasr = __builtin_get_texasr();
+
+       printf("\n\n==============\n\n");
+       printf("Failure with error: %lx\n",   _TEXASR_FAILURE_CODE(texasr));
+       printf("Summary error     : %lx\n",   _TEXASR_FAILURE_SUMMARY(texasr));
+       printf("TFIAR exact       : %lx\n\n", _TEXASR_TFIAR_EXACT(texasr));
+
+       passed = 0;
+       return NULL;
+
+       /* HTM aborted but VMX0 is correct */
+value_match:
+//     printf("!");
+       return NULL;
+
+success:
+//     printf(".");
+       return NULL;
+}
+
+int tm_vmx_unavail_test()
+{
+       int threads;
+       pthread_t *thread;
+
+       SKIP_IF(!have_htm());
+
+       passed = 1;
+
+       threads = sysconf(_SC_NPROCESSORS_ONLN) * 4;
+       thread = malloc(sizeof(pthread_t)*threads);
+       if (!thread)
+               return EXIT_FAILURE;
+
+       for (uint64_t i = 0; i < threads; i++)
+               pthread_create(&thread[i], NULL, &worker, NULL);
+
+       for (uint64_t i = 0; i < threads; i++)
+               pthread_join(thread[i], NULL);
+
+       free(thread);
+
+       return passed ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+
+int main(int argc, char **argv)
+{
+       return test_harness(tm_vmx_unavail_test, "tm_vmx_unavail_test");
+}
index bce6037cf01d31a73178e44b911dc25c2b6d5929..32c3295929b01b47d2071f372a458fa7b8e5d60d 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/kvm_hyp.h>
 
 #define vtr_to_max_lr_idx(v)           ((v) & 0xf)
-#define vtr_to_nr_pri_bits(v)          (((u32)(v) >> 29) + 1)
+#define vtr_to_nr_pre_bits(v)          (((u32)(v) >> 26) + 1)
 
 static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
 {
@@ -135,13 +135,13 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
 
        if (used_lrs) {
                int i;
-               u32 nr_pri_bits;
+               u32 nr_pre_bits;
 
                cpu_if->vgic_elrsr = read_gicreg(ICH_ELSR_EL2);
 
                write_gicreg(0, ICH_HCR_EL2);
                val = read_gicreg(ICH_VTR_EL2);
-               nr_pri_bits = vtr_to_nr_pri_bits(val);
+               nr_pre_bits = vtr_to_nr_pre_bits(val);
 
                for (i = 0; i < used_lrs; i++) {
                        if (cpu_if->vgic_elrsr & (1 << i))
@@ -152,7 +152,7 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
                        __gic_v3_set_lr(0, i);
                }
 
-               switch (nr_pri_bits) {
+               switch (nr_pre_bits) {
                case 7:
                        cpu_if->vgic_ap0r[3] = read_gicreg(ICH_AP0R3_EL2);
                        cpu_if->vgic_ap0r[2] = read_gicreg(ICH_AP0R2_EL2);
@@ -162,7 +162,7 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
                        cpu_if->vgic_ap0r[0] = read_gicreg(ICH_AP0R0_EL2);
                }
 
-               switch (nr_pri_bits) {
+               switch (nr_pre_bits) {
                case 7:
                        cpu_if->vgic_ap1r[3] = read_gicreg(ICH_AP1R3_EL2);
                        cpu_if->vgic_ap1r[2] = read_gicreg(ICH_AP1R2_EL2);
@@ -198,7 +198,7 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
        struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
        u64 used_lrs = vcpu->arch.vgic_cpu.used_lrs;
        u64 val;
-       u32 nr_pri_bits;
+       u32 nr_pre_bits;
        int i;
 
        /*
@@ -217,12 +217,12 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
        }
 
        val = read_gicreg(ICH_VTR_EL2);
-       nr_pri_bits = vtr_to_nr_pri_bits(val);
+       nr_pre_bits = vtr_to_nr_pre_bits(val);
 
        if (used_lrs) {
                write_gicreg(cpu_if->vgic_hcr, ICH_HCR_EL2);
 
-               switch (nr_pri_bits) {
+               switch (nr_pre_bits) {
                case 7:
                        write_gicreg(cpu_if->vgic_ap0r[3], ICH_AP0R3_EL2);
                        write_gicreg(cpu_if->vgic_ap0r[2], ICH_AP0R2_EL2);
@@ -232,7 +232,7 @@ void __hyp_text __vgic_v3_restore_state(struct kvm_vcpu *vcpu)
                        write_gicreg(cpu_if->vgic_ap0r[0], ICH_AP0R0_EL2);
                }
 
-               switch (nr_pri_bits) {
+               switch (nr_pre_bits) {
                case 7:
                        write_gicreg(cpu_if->vgic_ap1r[3], ICH_AP1R3_EL2);
                        write_gicreg(cpu_if->vgic_ap1r[2], ICH_AP1R2_EL2);
index 313ee646480f4d88264664d7393fcb39969609ba..a2d63247d1bbe00ca2693197c3f1e73963ad1c62 100644 (file)
@@ -295,6 +295,13 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size)
        assert_spin_locked(&kvm->mmu_lock);
        pgd = kvm->arch.pgd + stage2_pgd_index(addr);
        do {
+               /*
+                * Make sure the page table is still active, as another thread
+                * could have possibly freed the page table, while we released
+                * the lock.
+                */
+               if (!READ_ONCE(kvm->arch.pgd))
+                       break;
                next = stage2_pgd_addr_end(addr, end);
                if (!stage2_pgd_none(*pgd))
                        unmap_stage2_puds(kvm, pgd, addr, next);
@@ -829,22 +836,22 @@ void stage2_unmap_vm(struct kvm *kvm)
  * Walks the level-1 page table pointed to by kvm->arch.pgd and frees all
  * underlying level-2 and level-3 tables before freeing the actual level-1 table
  * and setting the struct pointer to NULL.
- *
- * Note we don't need locking here as this is only called when the VM is
- * destroyed, which can only be done once.
  */
 void kvm_free_stage2_pgd(struct kvm *kvm)
 {
-       if (kvm->arch.pgd == NULL)
-               return;
+       void *pgd = NULL;
 
        spin_lock(&kvm->mmu_lock);
-       unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
+       if (kvm->arch.pgd) {
+               unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
+               pgd = READ_ONCE(kvm->arch.pgd);
+               kvm->arch.pgd = NULL;
+       }
        spin_unlock(&kvm->mmu_lock);
 
        /* Free the HW pgd, one page at a time */
-       free_pages_exact(kvm->arch.pgd, S2_PGD_SIZE);
-       kvm->arch.pgd = NULL;
+       if (pgd)
+               free_pages_exact(pgd, S2_PGD_SIZE);
 }
 
 static pud_t *stage2_get_pud(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
@@ -1170,11 +1177,13 @@ static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
                 * large. Otherwise, we may see kernel panics with
                 * CONFIG_DETECT_HUNG_TASK, CONFIG_LOCKUP_DETECTOR,
                 * CONFIG_LOCKDEP. Additionally, holding the lock too long
-                * will also starve other vCPUs.
+                * will also starve other vCPUs. We have to also make sure
+                * that the page tables are not freed while we released
+                * the lock.
                 */
-               if (need_resched() || spin_needbreak(&kvm->mmu_lock))
-                       cond_resched_lock(&kvm->mmu_lock);
-
+               cond_resched_lock(&kvm->mmu_lock);
+               if (!READ_ONCE(kvm->arch.pgd))
+                       break;
                next = stage2_pgd_addr_end(addr, end);
                if (stage2_pgd_present(*pgd))
                        stage2_wp_puds(pgd, addr, next);
index dc68e2e424abf301151f4a610d412ea4b9109831..3a0b8999f011c6e3e1ff6ea7699577879a651fd3 100644 (file)
@@ -242,8 +242,11 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
         * If we are creating a VCPU with a GICv3 we must also register the
         * KVM io device for the redistributor that belongs to this VCPU.
         */
-       if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+       if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
+               mutex_lock(&vcpu->kvm->lock);
                ret = vgic_register_redist_iodev(vcpu);
+               mutex_unlock(&vcpu->kvm->lock);
+       }
        return ret;
 }
 
index 99da1a207c19b0563030bf4ad842d8d805b1b153..201d5e2e973dd4504c1f41747b2f07bb797ade11 100644 (file)
@@ -586,7 +586,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
        if (!vgic_v3_check_base(kvm))
                return -EINVAL;
 
-       rd_base = vgic->vgic_redist_base + kvm_vcpu_get_idx(vcpu) * SZ_64K * 2;
+       rd_base = vgic->vgic_redist_base + vgic->vgic_redist_free_offset;
        sgi_base = rd_base + SZ_64K;
 
        kvm_iodevice_init(&rd_dev->dev, &kvm_io_gic_ops);
@@ -614,11 +614,15 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
        mutex_lock(&kvm->slots_lock);
        ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, sgi_base,
                                      SZ_64K, &sgi_dev->dev);
-       mutex_unlock(&kvm->slots_lock);
-       if (ret)
+       if (ret) {
                kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS,
                                          &rd_dev->dev);
+               goto out;
+       }
 
+       vgic->vgic_redist_free_offset += 2 * SZ_64K;
+out:
+       mutex_unlock(&kvm->slots_lock);
        return ret;
 }
 
@@ -644,10 +648,12 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm)
 
        if (ret) {
                /* The current c failed, so we start with the previous one. */
+               mutex_lock(&kvm->slots_lock);
                for (c--; c >= 0; c--) {
                        vcpu = kvm_get_vcpu(kvm, c);
                        vgic_unregister_redist_iodev(vcpu);
                }
+               mutex_unlock(&kvm->slots_lock);
        }
 
        return ret;
index a65757aab6d32cef8fff2306e80fb6df0486bbc7..504b4bd0d651cf820eec843a325c649e0d1bd181 100644 (file)
@@ -149,6 +149,13 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        if (irq->hw) {
                val |= GICH_LR_HW;
                val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT;
+               /*
+                * Never set pending+active on a HW interrupt, as the
+                * pending state is kept at the physical distributor
+                * level.
+                */
+               if (irq->active && irq_is_pending(irq))
+                       val &= ~GICH_LR_PENDING_BIT;
        } else {
                if (irq->config == VGIC_CONFIG_LEVEL)
                        val |= GICH_LR_EOI;
index 8fa737edde6f2f9458fc0a6a33faa4c8c9fa810e..6fe3f003636a311d055581ee6a8133d0951fd3f2 100644 (file)
@@ -127,6 +127,13 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        if (irq->hw) {
                val |= ICH_LR_HW;
                val |= ((u64)irq->hwintid) << ICH_LR_PHYS_ID_SHIFT;
+               /*
+                * Never set pending+active on a HW interrupt, as the
+                * pending state is kept at the physical distributor
+                * level.
+                */
+               if (irq->active && irq_is_pending(irq))
+                       val &= ~ICH_LR_PENDING_BIT;
        } else {
                if (irq->config == VGIC_CONFIG_LEVEL)
                        val |= ICH_LR_EOI;