Merge tag 'imx-defconfig-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawng...
authorArnd Bergmann <arnd@arndb.de>
Wed, 22 Jul 2020 19:39:30 +0000 (21:39 +0200)
committerArnd Bergmann <arnd@arndb.de>
Wed, 22 Jul 2020 19:39:30 +0000 (21:39 +0200)
i.MX defconfig update for 5.9:

- Enable PCA9450 regulator driver in arm64 defconfig.
- Enable RV8803 RTC and FSL_SAI audio support in arm64 defconfig to make
  it useful for Kontron sl28 boards.
- Enable i.MX8MM clock and pinctrl driver in imx_v6_v7_defconfig to get
  AARCH32 mode kernel work on AARCH64 hardware.

* tag 'imx-defconfig-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  ARM: imx_v6_v7_defconfig: Support i.MX8MM
  arm64: defconfig: enable RTC and audio support on Kontron sl28 boards
  arm64: defconfig: add pca9450 pmic driver

Link: https://lore.kernel.org/r/20200720085536.24138-5-shawnguo@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
460 files changed:
Documentation/ABI/testing/sysfs-bus-papr-pmem [new file with mode: 0644]
Documentation/arm64/sve.rst
Documentation/driver-api/media/v4l2-subdev.rst
Documentation/filesystems/dax.txt
Documentation/filesystems/ext4/verity.rst
Documentation/gpu/amdgpu.rst
Documentation/i2c/smbus-protocol.rst
Documentation/powerpc/papr_hcalls.rst
Documentation/sh/index.rst
Documentation/userspace-api/media/conf_nitpick.py
MAINTAINERS
Makefile
arch/arm/configs/exynos_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/pxa_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/sunxi_defconfig
arch/arm/configs/tegra_defconfig
arch/arm/kernel/ftrace.c
arch/arm/kernel/kgdb.c
arch/arm/kernel/traps.c
arch/arm/mm/alignment.c
arch/arm64/Kconfig
arch/arm64/Kconfig.debug
arch/arm64/Makefile
arch/arm64/configs/defconfig
arch/arm64/include/asm/pgtable.h
arch/arm64/kernel/fpsimd.c
arch/arm64/kernel/hw_breakpoint.c
arch/arm64/kernel/insn.c
arch/arm64/kernel/machine_kexec_file.c
arch/arm64/kernel/traps.c
arch/arm64/mm/init.c
arch/arm64/mm/mmu.c
arch/csky/kernel/ftrace.c
arch/ia64/include/asm/sections.h
arch/ia64/kernel/ftrace.c
arch/ia64/kernel/unwind_i.h
arch/mips/kernel/kprobes.c
arch/nds32/kernel/ftrace.c
arch/parisc/kernel/ftrace.c
arch/parisc/kernel/kgdb.c
arch/parisc/kernel/process.c
arch/parisc/lib/memcpy.c
arch/powerpc/include/asm/nohash/32/pgtable.h
arch/powerpc/include/asm/sections.h
arch/powerpc/include/uapi/asm/papr_pdsm.h [new file with mode: 0644]
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/module_64.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/trace/ftrace.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/lib/inst.c
arch/powerpc/oprofile/backtrace.c
arch/powerpc/perf/callchain_32.c
arch/powerpc/perf/callchain_64.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/cell/spu_callbacks.c
arch/powerpc/platforms/pseries/papr_scm.c
arch/powerpc/sysdev/fsl_pci.c
arch/riscv/include/asm/cmpxchg.h
arch/riscv/kernel/ftrace.c
arch/riscv/kernel/kgdb.c
arch/riscv/kernel/patch.c
arch/riscv/kernel/sys_riscv.c
arch/riscv/kernel/traps.c
arch/riscv/mm/pageattr.c
arch/s390/Kconfig
arch/s390/crypto/prng.c
arch/s390/include/asm/syscall.h
arch/s390/include/asm/vdso.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/entry.S
arch/s390/kernel/ftrace.c
arch/s390/kernel/ipl.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/time.c
arch/s390/kernel/uv.c
arch/s390/kernel/vdso64/Makefile
arch/s390/kernel/vdso64/clock_getres.S
arch/s390/mm/fault.c
arch/sh/kernel/ftrace.c
arch/sh/kernel/traps.c
arch/um/kernel/maccess.c
arch/x86/include/asm/ptrace.h
arch/x86/kernel/dumpstack.c
arch/x86/kernel/ftrace.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/kprobes/opt.c
arch/x86/kernel/probe_roms.c
arch/x86/kernel/traps.c
arch/x86/mm/fault.c
arch/x86/mm/init_32.c
arch/x86/mm/maccess.c
arch/x86/pci/pcbios.c
arch/x86/platform/intel-mid/sfi.c
arch/x86/purgatory/Makefile
arch/x86/xen/enlighten_pv.c
block/blk-mq-tag.c
block/blk-mq.c
block/partitions/ldm.c
block/partitions/ldm.h
crypto/algboss.c
crypto/algif_skcipher.c
crypto/drbg.c
drivers/amba/tegra-ahb.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/sata_rcar.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_protocol.h
drivers/block/loop.c
drivers/block/rbd.c
drivers/char/hw_random/ks-sa-rng.c
drivers/char/mem.c
drivers/crypto/caam/Kconfig
drivers/crypto/caam/ctrl.c
drivers/crypto/caam/desc.h
drivers/crypto/caam/pdb.h
drivers/crypto/ccp/sev-dev.c
drivers/crypto/chelsio/chcr_crypto.h
drivers/crypto/hisilicon/sgl.c
drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
drivers/dio/dio.c
drivers/dma/milbeaut-hdmac.c
drivers/dma/milbeaut-xdmac.c
drivers/dma/moxart-dma.c
drivers/dma/tegra20-apb-dma.c
drivers/dma/ti/edma.c
drivers/dma/ti/k3-udma.c
drivers/dma/timb_dma.c
drivers/firewire/core-cdev.c
drivers/firewire/core-transaction.c
drivers/firewire/core.h
drivers/firewire/nosy.c
drivers/firewire/ohci.c
drivers/firmware/dmi-sysfs.c
drivers/firmware/google/memconsole-coreboot.c
drivers/firmware/google/vpd.c
drivers/firmware/iscsi_ibft.c
drivers/firmware/pcdp.h
drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/display/dc/dsc/Makefile
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c
drivers/gpu/drm/amd/display/modules/color/color_gamma.c
drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c
drivers/gpu/drm/drm_encoder_slave.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/gt/intel_engine_cs.c
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/intel_ring.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/gt/selftest_hangcheck.c
drivers/gpu/drm/i915/gt/selftest_lrc.c
drivers/gpu/drm/i915/gt/selftest_mocs.c
drivers/gpu/drm/i915/gt/selftest_ring.c [new file with mode: 0644]
drivers/gpu/drm/i915/gt/selftest_rps.c
drivers/gpu/drm/i915/gt/selftest_timeline.c
drivers/gpu/drm/i915/gt/selftest_workarounds.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_priolist_types.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/selftests/i915_mock_selftests.h
drivers/hwtracing/stm/policy.c
drivers/hwtracing/stm/stm.h
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-smbus.c
drivers/input/serio/hp_sdc.c
drivers/md/bcache/btree.c
drivers/md/bcache/super.c
drivers/media/usb/pwc/pwc.h
drivers/mfd/mt6360-core.c
drivers/misc/kgdbts.c
drivers/net/bareudp.c
drivers/net/can/peak_canfd/peak_pciefd_main.c
drivers/net/dsa/sja1105/sja1105_ptp.c
drivers/net/ethernet/atheros/alx/main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mediatek/mtk_star_emac.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
drivers/net/ethernet/rocker/rocker_main.c
drivers/net/ethernet/xilinx/xilinx_axienet.h
drivers/nvdimm/region_devs.c
drivers/oprofile/cpu_buffer.h
drivers/phy/samsung/phy-samsung-usb2.h
drivers/pinctrl/freescale/pinctrl-imx.c
drivers/pinctrl/pinctrl-mcp23s08_spi.c
drivers/pinctrl/pinctrl-single.c
drivers/pinctrl/qcom/pinctrl-ipq6018.c
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
drivers/pinctrl/tegra/pinctrl-tegra.c
drivers/rapidio/rio-scan.c
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c
drivers/s390/crypto/zcrypt_ep11misc.c
drivers/s390/virtio/virtio_ccw.c
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
drivers/scsi/ipr.c
drivers/scsi/isci/init.c
drivers/scsi/mvsas/mv_init.c
drivers/scsi/pm8001/pm8001_init.c
drivers/scsi/ufs/ufs_bsg.c
drivers/soc/ti/knav_qmss.h
drivers/video/backlight/tosa_lcd.c
drivers/video/fbdev/hpfb.c
drivers/w1/w1_netlink.h
fs/afs/dir.c
fs/afs/dir_silly.c
fs/afs/file.c
fs/afs/flock.c
fs/afs/fs_operation.c
fs/afs/fs_probe.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/main.c
fs/afs/misc.c
fs/afs/server.c
fs/afs/write.c
fs/afs/yfsclient.c
fs/aio.c
fs/block_dev.c
fs/ext4/Makefile
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/ext4/super.c
fs/ext4/verity.c
fs/ext4/xattr.c
fs/ext4/xattr.h
fs/ext4/xattr_hurd.c [new file with mode: 0644]
fs/io-wq.c
fs/io-wq.h
fs/io_uring.c
fs/jbd2/journal.c
fs/jffs2/nodelist.h
fs/jffs2/summary.h
fs/proc/bootconfig.c
fs/proc/kcore.c
fs/squashfs/squashfs_fs.h
include/asm-generic/hugetlb.h
include/drm/drm_displayid.h
include/keys/encrypted-type.h
include/keys/rxrpc-type.h
include/linux/can/skb.h
include/linux/cb710.h
include/linux/ceph/libceph.h
include/linux/compiler_types.h
include/linux/dmaengine.h
include/linux/fs.h
include/linux/fscache-cache.h
include/linux/i2c.h
include/linux/jbd2.h
include/linux/kexec.h
include/linux/kprobes.h
include/linux/kvm_host.h
include/linux/libata.h
include/linux/overflow.h
include/linux/pgtable.h
include/linux/psp-sev.h
include/linux/sctp.h
include/linux/tifm.h
include/linux/uaccess.h
include/net/netfilter/nf_flow_table.h
include/net/tc_act/tc_ct.h
include/trace/events/block.h
include/uapi/linux/fs.h
include/uapi/linux/ndctl.h
include/uapi/linux/xattr.h
kernel/debug/debug_core.c
kernel/debug/gdbstub.c
kernel/debug/kdb/kdb_main.c
kernel/debug/kdb/kdb_support.c
kernel/dma/Kconfig
kernel/dma/pool.c
kernel/kprobes.c
kernel/kthread.c
kernel/trace/blktrace.c
kernel/trace/bpf_trace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_entries.h
kernel/trace/trace_export.c
kernel/trace/trace_functions.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_probe.c
kernel/trace/trace_probe.h
kernel/workqueue.c
lib/Kconfig.debug
lib/seq_buf.c
lib/test_lockup.c
lib/test_objagg.c
mm/debug.c
mm/gup.c
mm/maccess.c
mm/rodata_test.c
mm/slub.c
net/ceph/ceph_common.c
net/ceph/osd_client.c
net/ipv4/tcp_input.c
net/ipv6/mcast.c
net/mptcp/protocol.h
net/mptcp/subflow.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_flow_table_core.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_set_pipapo.c
net/netfilter/nft_set_rbtree.c
net/rds/ib.h
net/sched/act_ct.c
samples/Kconfig
samples/ftrace/sample-trace-array.c
samples/mei/mei-amt-version.c
samples/watch_queue/Makefile
scripts/Kbuild.include
scripts/Kconfig.include
scripts/decode_stacktrace.sh
scripts/headers_install.sh
scripts/recordmcount.h
security/integrity/integrity.h
security/selinux/ss/conditional.c
security/selinux/ss/services.c
sound/soc/sof/probe.h
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/msr-index.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/arch/x86/include/uapi/asm/unistd.h
tools/arch/x86/include/uapi/asm/vmx.h
tools/bootconfig/main.c
tools/bootconfig/test-bootconfig.sh
tools/include/uapi/asm-generic/unistd.h
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/fcntl.h
tools/include/uapi/linux/fs.h
tools/include/uapi/linux/fscrypt.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/stat.h
tools/include/uapi/linux/vhost.h
tools/lib/traceevent/event-parse.c
tools/perf/Makefile.config
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/builtin-report.c
tools/perf/builtin-script.c
tools/perf/trace/beauty/statx.c
tools/perf/util/bpf-prologue.c
tools/perf/util/parse-events.y
tools/perf/util/pmu.h
tools/perf/util/probe-event.c
tools/perf/util/probe-file.c
tools/perf/util/stat-display.c
tools/testing/nvdimm/test/nfit_test.h
tools/testing/selftests/ftrace/ftracetest
tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc
tools/testing/selftests/ftrace/test.d/00basic/trace_pipe.tc
tools/testing/selftests/ftrace/test.d/direct/kprobe-direct.tc
tools/testing/selftests/ftrace/test.d/dynevent/add_remove_kprobe.tc
tools/testing/selftests/ftrace/test.d/dynevent/add_remove_synth.tc
tools/testing/selftests/ftrace/test.d/dynevent/clear_select_events.tc
tools/testing/selftests/ftrace/test.d/dynevent/generic_clear_event.tc
tools/testing/selftests/ftrace/test.d/event/event-enable.tc
tools/testing/selftests/ftrace/test.d/event/event-no-pid.tc
tools/testing/selftests/ftrace/test.d/event/event-pid.tc
tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-glob.tc
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-notrace-pid.tc
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-pid.tc
tools/testing/selftests/ftrace/test.d/ftrace/func-filter-stacktrace.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_cpumask.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_mod_trace.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_profile_stat.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_set_ftrace_file.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_stack_tracer.tc
tools/testing/selftests/ftrace/test.d/ftrace/func_traceonoff_triggers.tc
tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc
tools/testing/selftests/ftrace/test.d/functions
tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
tools/testing/selftests/ftrace/test.d/instances/instance.tc
tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc
tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_comm.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_string.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_symbol.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_syntax.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_type.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_module.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_multiprobe.tc
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc
tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_maxactive.tc
tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
tools/testing/selftests/ftrace/test.d/kprobe/probepoint.tc
tools/testing/selftests/ftrace/test.d/kprobe/profile.tc
tools/testing/selftests/ftrace/test.d/kprobe/uprobe_syntax_errors.tc
tools/testing/selftests/ftrace/test.d/preemptirq/irqsoff_tracer.tc
tools/testing/selftests/ftrace/test.d/template
tools/testing/selftests/ftrace/test.d/tracer/wakeup.tc
tools/testing/selftests/ftrace/test.d/tracer/wakeup_rt.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-action-hist-xfail.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-field-variable-support.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-inter-event-combined-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-multi-actions-accept.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmatch-onmax-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onmax-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-createremove.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-syntax.tc
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-trace-action-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-eventonoff.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-filter.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-mod.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-syntax-errors.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-multihist.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-snapshot.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-stacktrace.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-hist.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-snapshot.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-synthetic-kernel.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-trace-marker-synthetic.tc
tools/testing/selftests/ftrace/test.d/trigger/trigger-traceonoff.tc
tools/testing/selftests/seccomp/seccomp_bpf.c

diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem
new file mode 100644 (file)
index 0000000..5b10d03
--- /dev/null
@@ -0,0 +1,27 @@
+What:          /sys/bus/nd/devices/nmemX/papr/flags
+Date:          Apr, 2020
+KernelVersion: v5.8
+Contact:       linuxppc-dev <linuxppc-dev@lists.ozlabs.org>, linux-nvdimm@lists.01.org,
+Description:
+               (RO) Report flags indicating various states of a
+               papr-pmem NVDIMM device. Each flag maps to a one or
+               more bits set in the dimm-health-bitmap retrieved in
+               response to H_SCM_HEALTH hcall. The details of the bit
+               flags returned in response to this hcall is available
+               at 'Documentation/powerpc/papr_hcalls.rst' . Below are
+               the flags reported in this sysfs file:
+
+               * "not_armed"   : Indicates that NVDIMM contents will not
+                                 survive a power cycle.
+               * "flush_fail"  : Indicates that NVDIMM contents
+                                 couldn't be flushed during last
+                                 shut-down event.
+               * "restore_fail": Indicates that NVDIMM contents
+                                 couldn't be restored during NVDIMM
+                                 initialization.
+               * "encrypted"   : NVDIMM contents are encrypted.
+               * "smart_notify": There is health event for the NVDIMM.
+               * "scrubbed"    : Indicating that contents of the
+                                 NVDIMM have been scrubbed.
+               * "locked"      : Indicating that NVDIMM contents cant
+                                 be modified until next power cycle.
index 5689c74..bfd55f4 100644 (file)
@@ -186,7 +186,7 @@ prctl(PR_SVE_SET_VL, unsigned long arg)
 
     flags:
 
-       PR_SVE_SET_VL_INHERIT
+       PR_SVE_VL_INHERIT
 
            Inherit the current vector length across execve().  Otherwise, the
            vector length is reset to the system default at execve().  (See
@@ -247,7 +247,7 @@ prctl(PR_SVE_GET_VL)
 
     The following flag may be OR-ed into the result:
 
-       PR_SVE_SET_VL_INHERIT
+       PR_SVE_VL_INHERIT
 
            Vector length will be inherited across execve().
 
@@ -393,7 +393,7 @@ The regset data starts with struct user_sve_header, containing:
 * At every execve() call, the new vector length of the new process is set to
   the system default vector length, unless
 
-    * PR_SVE_SET_VL_INHERIT (or equivalently SVE_PT_VL_INHERIT) is set for the
+    * PR_SVE_VL_INHERIT (or equivalently SVE_PT_VL_INHERIT) is set for the
       calling thread, or
 
     * a deferred vector length change is pending, established via the
index 6e71f67..bc7e1fc 100644 (file)
@@ -451,7 +451,7 @@ The bridge driver also has some helper functions it can use:
                                        "module_foo", "chipid", 0x36, NULL);
 
 This loads the given module (can be ``NULL`` if no module needs to be loaded)
-and calls :c:func:`i2c_new_device` with the given ``i2c_adapter`` and
+and calls :c:func:`i2c_new_client_device` with the given ``i2c_adapter`` and
 chip/address arguments. If all goes well, then it registers the subdev with
 the v4l2_device.
 
index 8e26707..8fdb78f 100644 (file)
@@ -25,7 +25,7 @@ size when creating the filesystem.
 Currently 3 filesystems support DAX: ext2, ext4 and xfs.  Enabling DAX on them
 is different.
 
-Enabling DAX on ext4 and ext2
+Enabling DAX on ext2
 -----------------------------
 
 When mounting the filesystem, use the "-o dax" option on the command line or
@@ -33,8 +33,8 @@ add 'dax' to the options in /etc/fstab.  This works to enable DAX on all files
 within the filesystem.  It is equivalent to the '-o dax=always' behavior below.
 
 
-Enabling DAX on xfs
--------------------
+Enabling DAX on xfs and ext4
+----------------------------
 
 Summary
 -------
index 3e4c0ee..e99ff3f 100644 (file)
@@ -39,3 +39,6 @@ is encrypted as well as the data itself.
 
 Verity files cannot have blocks allocated past the end of the verity
 metadata.
+
+Verity and DAX are not compatible and attempts to set both of these flags
+on a file will fail.
index 4cc7432..1711235 100644 (file)
@@ -197,11 +197,14 @@ pp_power_profile_mode
 .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
    :doc: pp_power_profile_mode
 
-busy_percent
-~~~~~~~~~~~~
+*_busy_percent
+~~~~~~~~~~~~~~
 
 .. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
-   :doc: busy_percent
+   :doc: gpu_busy_percent
+
+.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
+   :doc: mem_busy_percent
 
 GPU Product Information
 =======================
index c2e2963..64689d1 100644 (file)
@@ -57,7 +57,7 @@ SMBus Quick Command
 
 This sends a single bit to the device, at the place of the Rd/Wr bit::
 
-  A Addr Rd/Wr [A] P
+  S Addr Rd/Wr [A] P
 
 Functionality flag: I2C_FUNC_SMBUS_QUICK
 
index 3493631..48fcf12 100644 (file)
@@ -220,13 +220,51 @@ from the LPAR memory.
 **H_SCM_HEALTH**
 
 | Input: drcIndex
-| Out: *health-bitmap, health-bit-valid-bitmap*
+| Out: *health-bitmap (r4), health-bit-valid-bitmap (r5)*
 | Return Value: *H_Success, H_Parameter, H_Hardware*
 
 Given a DRC Index return the info on predictive failure and overall health of
-the NVDIMM. The asserted bits in the health-bitmap indicate a single predictive
-failure and health-bit-valid-bitmap indicate which bits in health-bitmap are
-valid.
+the PMEM device. The asserted bits in the health-bitmap indicate one or more states
+(described in table below) of the PMEM device and health-bit-valid-bitmap indicate
+which bits in health-bitmap are valid. The bits are reported in
+reverse bit ordering for example a value of 0xC400000000000000
+indicates bits 0, 1, and 5 are valid.
+
+Health Bitmap Flags:
+
++------+-----------------------------------------------------------------------+
+|  Bit |               Definition                                              |
++======+=======================================================================+
+|  00  | PMEM device is unable to persist memory contents.                     |
+|      | If the system is powered down, nothing will be saved.                 |
++------+-----------------------------------------------------------------------+
+|  01  | PMEM device failed to persist memory contents. Either contents were   |
+|      | not saved successfully on power down or were not restored properly on |
+|      | power up.                                                             |
++------+-----------------------------------------------------------------------+
+|  02  | PMEM device contents are persisted from previous IPL. The data from   |
+|      | the last boot were successfully restored.                             |
++------+-----------------------------------------------------------------------+
+|  03  | PMEM device contents are not persisted from previous IPL. There was no|
+|      | data to restore from the last boot.                                   |
++------+-----------------------------------------------------------------------+
+|  04  | PMEM device memory life remaining is critically low                   |
++------+-----------------------------------------------------------------------+
+|  05  | PMEM device will be garded off next IPL due to failure                |
++------+-----------------------------------------------------------------------+
+|  06  | PMEM device contents cannot persist due to current platform health    |
+|      | status. A hardware failure may prevent data from being saved or       |
+|      | restored.                                                             |
++------+-----------------------------------------------------------------------+
+|  07  | PMEM device is unable to persist memory contents in certain conditions|
++------+-----------------------------------------------------------------------+
+|  08  | PMEM device is encrypted                                              |
++------+-----------------------------------------------------------------------+
+|  09  | PMEM device has successfully completed a requested erase or secure    |
+|      | erase procedure.                                                      |
++------+-----------------------------------------------------------------------+
+|10:63 | Reserved / Unused                                                     |
++------+-----------------------------------------------------------------------+
 
 **H_SCM_PERFORMANCE_STATS**
 
index bc8db7b..0bd405a 100644 (file)
@@ -16,18 +16,6 @@ Store Queue API
 .. kernel-doc:: arch/sh/kernel/cpu/sh4/sq.c
    :export:
 
-SH-5
-----
-
-TLB Interfaces
-~~~~~~~~~~~~~~
-
-.. kernel-doc:: arch/sh/mm/tlb-sh5.c
-   :internal:
-
-.. kernel-doc:: arch/sh/include/asm/tlb_64.h
-   :internal:
-
 Machine Specific Interfaces
 ===========================
 
index d0c50d7..0a8e236 100644 (file)
@@ -27,7 +27,7 @@ nitpick_ignore = [
     ("c:func", "copy_to_user"),
     ("c:func", "determine_valid_ioctls"),
     ("c:func", "ERR_PTR"),
-    ("c:func", "i2c_new_device"),
+    ("c:func", "i2c_new_client_device"),
     ("c:func", "ioctl"),
     ("c:func", "IS_ERR"),
     ("c:func", "KERNEL_VERSION"),
index 68f21d4..7b5ffd6 100644 (file)
@@ -11369,14 +11369,6 @@ L:     dmaengine@vger.kernel.org
 S:     Supported
 F:     drivers/dma/at_xdmac.c
 
-MICROSEMI ETHERNET SWITCH DRIVER
-M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
-M:     Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
-L:     netdev@vger.kernel.org
-S:     Supported
-F:     drivers/net/ethernet/mscc/
-F:     include/soc/mscc/ocelot*
-
 MICROSEMI MIPS SOCS
 M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
 M:     Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
@@ -12335,6 +12327,18 @@ M:     Peter Zijlstra <peterz@infradead.org>
 S:     Supported
 F:     tools/objtool/
 
+OCELOT ETHERNET SWITCH DRIVER
+M:     Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
+M:     Vladimir Oltean <vladimir.oltean@nxp.com>
+M:     Claudiu Manoil <claudiu.manoil@nxp.com>
+M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     drivers/net/dsa/ocelot/*
+F:     drivers/net/ethernet/mscc/
+F:     include/soc/mscc/ocelot*
+F:     net/dsa/tag_ocelot.c
+
 OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
 M:     Frederic Barrat <fbarrat@linux.ibm.com>
 M:     Andrew Donnellan <ajd@linux.ibm.com>
@@ -14192,6 +14196,15 @@ L:     dmaengine@vger.kernel.org
 S:     Supported
 F:     drivers/dma/qcom/hidma*
 
+QUALCOMM I2C CCI DRIVER
+M:     Loic Poulain <loic.poulain@linaro.org>
+M:     Robert Foss <robert.foss@linaro.org>
+L:     linux-i2c@vger.kernel.org
+L:     linux-arm-msm@vger.kernel.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/i2c/i2c-qcom-cci.txt
+F:     drivers/i2c/busses/i2c-qcom-cci.c
+
 QUALCOMM IOMMU
 M:     Rob Clark <robdclark@gmail.com>
 L:     iommu@lists.linux-foundation.org
@@ -14534,7 +14547,7 @@ F:      Documentation/devicetree/bindings/i2c/renesas,iic-emev2.txt
 F:     drivers/i2c/busses/i2c-emev2.c
 
 RENESAS ETHERNET DRIVERS
-R:     Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+R:     Sergei Shtylyov <sergei.shtylyov@gmail.com>
 L:     netdev@vger.kernel.org
 L:     linux-renesas-soc@vger.kernel.org
 F:     Documentation/devicetree/bindings/net/renesas,*.txt
@@ -18254,14 +18267,6 @@ S:     Maintained
 F:     drivers/input/serio/userio.c
 F:     include/uapi/linux/userio.h
 
-VITESSE FELIX ETHERNET SWITCH DRIVER
-M:     Vladimir Oltean <vladimir.oltean@nxp.com>
-M:     Claudiu Manoil <claudiu.manoil@nxp.com>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/dsa/ocelot/*
-F:     net/dsa/tag_ocelot.c
-
 VIVID VIRTUAL VIDEO DRIVER
 M:     Hans Verkuil <hverkuil@xs4all.nl>
 L:     linux-media@vger.kernel.org
index ae5d822..ac2c61c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 8
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
@@ -828,7 +828,7 @@ endif
 
 ifdef CONFIG_DEBUG_INFO_COMPRESSED
 DEBUG_CFLAGS   += -gz=zlib
-KBUILD_AFLAGS  += -Wa,--compress-debug-sections=zlib
+KBUILD_AFLAGS  += -gz=zlib
 KBUILD_LDFLAGS += --compress-debug-sections=zlib
 endif
 
@@ -1336,16 +1336,6 @@ dt_binding_check: scripts_dtc
 # ---------------------------------------------------------------------------
 # Modules
 
-# install modules.builtin regardless of CONFIG_MODULES
-PHONY += _builtin_inst_
-_builtin_inst_:
-       @mkdir -p $(MODLIB)/
-       @cp -f modules.builtin $(MODLIB)/
-       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
-
-PHONY += install
-install: _builtin_inst_
-
 ifdef CONFIG_MODULES
 
 # By default, build modules as well
@@ -1389,7 +1379,7 @@ PHONY += modules_install
 modules_install: _modinst_ _modinst_post
 
 PHONY += _modinst_
-_modinst_: _builtin_inst_
+_modinst_:
        @rm -rf $(MODLIB)/kernel
        @rm -f $(MODLIB)/source
        @mkdir -p $(MODLIB)/kernel
@@ -1399,6 +1389,8 @@ _modinst_: _builtin_inst_
                ln -s $(CURDIR) $(MODLIB)/build ; \
        fi
        @sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
+       @cp -f modules.builtin $(MODLIB)/
+       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
 # This depmod is only for convenience to give the initial
index 374fbff..6e8b5ff 100644 (file)
@@ -166,7 +166,9 @@ CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
-CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_DEV=y
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC=y
 CONFIG_MFD_MAX14577=y
 CONFIG_MFD_MAX77686=y
 CONFIG_MFD_MAX77693=y
index 9554391..e9e76e3 100644 (file)
@@ -314,6 +314,7 @@ CONFIG_INPUT_MAX77693_HAPTIC=m
 CONFIG_INPUT_MAX8997_HAPTIC=m
 CONFIG_INPUT_CPCAP_PWRBUTTON=m
 CONFIG_INPUT_AXP20X_PEK=m
+CONFIG_INPUT_DA9063_ONKEY=m
 CONFIG_INPUT_ADXL34X=m
 CONFIG_INPUT_STPMIC1_ONKEY=y
 CONFIG_SERIO_AMBAKMI=y
@@ -520,6 +521,7 @@ CONFIG_TEGRA_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=y
 CONFIG_DIGICOLOR_WATCHDOG=y
 CONFIG_RENESAS_WDT=m
+CONFIG_RENESAS_RZAWDT=m
 CONFIG_STPMIC1_WATCHDOG=y
 CONFIG_BCM47XX_WDT=y
 CONFIG_BCM2835_WDT=y
@@ -618,6 +620,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_MMP_CAMERA=m
 CONFIG_VIDEO_ASPEED=m
 CONFIG_VIDEO_STM32_DCMI=m
+CONFIG_VIDEO_RENESAS_CEU=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
 CONFIG_VIDEO_S5P_FIMC=m
 CONFIG_VIDEO_S5P_MIPI_CSIS=m
@@ -640,6 +643,8 @@ CONFIG_VIDEO_VIVID=m
 CONFIG_CEC_PLATFORM_DRIVERS=y
 CONFIG_CEC_SAMSUNG_S5P=m
 CONFIG_VIDEO_ADV7180=m
+CONFIG_VIDEO_ADV7604=m
+CONFIG_VIDEO_ADV7604_CEC=y
 CONFIG_VIDEO_ML86V7667=m
 CONFIG_IMX_IPUV3_CORE=m
 CONFIG_DRM=y
@@ -901,6 +906,7 @@ CONFIG_RTC_DRV_EFI=m
 CONFIG_RTC_DRV_DIGICOLOR=m
 CONFIG_RTC_DRV_S3C=m
 CONFIG_RTC_DRV_SA1100=m
+CONFIG_RTC_DRV_SH=m
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_AT91RM9200=m
 CONFIG_RTC_DRV_AT91SAM9=m
@@ -945,7 +951,7 @@ CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
 CONFIG_STAGING_BOARD=y
-CONFIG_MFD_CROS_EC=m
+CONFIG_MFD_CROS_EC_DEV=m
 CONFIG_CROS_EC_I2C=m
 CONFIG_CROS_EC_SPI=m
 CONFIG_COMMON_CLK_MAX77686=y
@@ -1126,3 +1132,6 @@ CONFIG_CMA_SIZE_MBYTES=64
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC=m
+CONFIG_CROS_EC_CHARDEV=m
index e6559e3..1dc7e9d 100644 (file)
@@ -391,7 +391,9 @@ CONFIG_SA1100_WATCHDOG=m
 CONFIG_MFD_AS3711=y
 CONFIG_MFD_BCM590XX=m
 CONFIG_MFD_AXP20X=y
-CONFIG_MFD_CROS_EC=m
+CONFIG_MFD_CROS_EC_DEV=m
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC=m
 CONFIG_CROS_EC_I2C=m
 CONFIG_CROS_EC_SPI=m
 CONFIG_MFD_ASIC3=y
index 9cf3143..bbedc42 100644 (file)
@@ -13,8 +13,6 @@ CONFIG_SMP=y
 CONFIG_SCHED_MC=y
 CONFIG_NR_CPUS=8
 CONFIG_HIGHMEM=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
@@ -67,6 +65,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_EDT_FT5X06=y
 CONFIG_TOUCHSCREEN_ST1232=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_DA9063_ONKEY=y
 CONFIG_INPUT_ADXL34X=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
@@ -90,6 +89,7 @@ CONFIG_PINCTRL_RZA1=y
 CONFIG_PINCTRL_RZA2=y
 CONFIG_GPIO_EM=y
 CONFIG_GPIO_RCAR=y
+CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCF857X=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_RMOBILE=y
@@ -101,6 +101,7 @@ CONFIG_RCAR_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_DA9063_WATCHDOG=y
 CONFIG_RENESAS_WDT=y
+CONFIG_RENESAS_RZAWDT=y
 CONFIG_MFD_AS3711=y
 CONFIG_MFD_DA9063=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -109,18 +110,19 @@ CONFIG_REGULATOR_DA9210=y
 CONFIG_REGULATOR_GPIO=y
 CONFIG_REGULATOR_MAX8973=y
 CONFIG_MEDIA_SUPPORT=y
+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_RENESAS_CEU=y
 CONFIG_VIDEO_RCAR_VIN=y
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_RENESAS_FDP1=y
 CONFIG_VIDEO_RENESAS_JPU=y
 CONFIG_VIDEO_RENESAS_VSP1=y
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 CONFIG_VIDEO_ADV7180=y
 CONFIG_VIDEO_ADV7604=y
+CONFIG_VIDEO_ADV7604_CEC=y
 CONFIG_VIDEO_ML86V7667=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
@@ -168,6 +170,7 @@ CONFIG_RTC_DRV_BQ32K=y
 CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_RX8581=y
 CONFIG_RTC_DRV_DA9063=y
+CONFIG_RTC_DRV_SH=y
 CONFIG_DMADEVICES=y
 CONFIG_RCAR_DMAC=y
 CONFIG_RENESAS_USB_DMAC=y
index b105ce7..2441261 100644 (file)
@@ -3,20 +3,19 @@ CONFIG_HIGH_RES_TIMERS=y
 CONFIG_CGROUPS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_PERF_EVENTS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=8
-CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_CMA=y
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_VFP=y
 CONFIG_NEON=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -24,9 +23,6 @@ CONFIG_INET=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
 # CONFIG_IPV6 is not set
 CONFIG_CAN=y
@@ -34,14 +30,12 @@ CONFIG_CAN_SUN4I=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_DMA_CMA=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 CONFIG_AHCI_SUNXI=y
 CONFIG_NETDEVICES=y
 CONFIG_SUN4I_EMAC=y
 # CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_CIRRUS is not set
 # CONFIG_NET_VENDOR_FARADAY is not set
@@ -65,6 +59,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_SUN4I=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_AXP20X_PEK=y
+CONFIG_SERIO_SUN4I_PS2=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=8
@@ -95,19 +90,37 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_AXP20X=y
 CONFIG_REGULATOR_GPIO=y
-CONFIG_MEDIA_SUPPORT=y
 CONFIG_RC_CORE=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_SUNXI=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_SUN4I_CSI=y
+CONFIG_VIDEO_SUN6I_CSI=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_SUN8I_DEINTERLACE=y
+CONFIG_VIDEO_SUN8I_ROTATE=y
 CONFIG_DRM=y
 CONFIG_DRM_SUN4I=y
+CONFIG_DRM_SUN4I_HDMI_CEC=y
+CONFIG_DRM_SUN8I_DW_HDMI=y
+CONFIG_DRM_PANEL_LVDS=y
+CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DRM_LIMA=y
 CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
 CONFIG_SND_SUN4I_CODEC=y
+CONFIG_SND_SUN8I_CODEC=y
 CONFIG_SND_SUN8I_CODEC_ANALOG=y
+CONFIG_SND_SUN4I_I2S=y
+CONFIG_SND_SUN4I_SPDIF=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
@@ -132,15 +145,18 @@ CONFIG_RTC_DRV_AC100=y
 CONFIG_RTC_DRV_SUNXI=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_SUN6I=y
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_VIDEO_SUNXI=y
+CONFIG_VIDEO_SUNXI_CEDRUS=y
+CONFIG_MAILBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
-CONFIG_EXTCON=y
 CONFIG_IIO=y
 CONFIG_AXP20X_ADC=y
 CONFIG_PWM=y
 CONFIG_PWM_SUN4I=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_SUN9I_USB=y
-CONFIG_NVMEM=y
 CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_EXT4_FS=y
 CONFIG_VFAT_FS=y
@@ -151,8 +167,10 @@ CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
+CONFIG_CRYPTO_DEV_SUN4I_SS=y
+CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG=y
+CONFIG_CRYPTO_DEV_SUN8I_CE=y
+CONFIG_CRYPTO_DEV_SUN8I_SS=y
+CONFIG_DMA_CMA=y
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_FS=y
-CONFIG_CRYPTO_DEV_ALLWINNER=y
-CONFIG_CRYPTO_DEV_SUN8I_CE=y
-CONFIG_CRYPTO_DEV_SUN4I_SS=y
index aa94369..fff5fae 100644 (file)
@@ -10,6 +10,8 @@ CONFIG_RT_GROUP_SCHED=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_DEBUG=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_ELF_CORE is not set
 CONFIG_EMBEDDED=y
@@ -18,11 +20,13 @@ CONFIG_SLAB=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_SMP=y
 CONFIG_HIGHMEM=y
+CONFIG_SECCOMP=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_KEXEC=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_TEGRA_CPUIDLE=y
@@ -63,11 +67,17 @@ CONFIG_BT_RFCOMM=y
 CONFIG_BT_BNEP=y
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_BCM=y
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_INPUT=y
 CONFIG_RFKILL_GPIO=y
+CONFIG_NFC=y
+CONFIG_NFC_HCI=y
+CONFIG_NFC_SHDLC=y
+CONFIG_NFC_PN544_I2C=y
 CONFIG_PCI=y
 CONFIG_PCIEPORTBUS=y
 CONFIG_PCI_MSI=y
@@ -106,20 +116,24 @@ CONFIG_INPUT_JOYDEV=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_TEGRA=y
+CONFIG_KEYBOARD_CAP11XX=y
 CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_ELAN=y
 CONFIG_TOUCHSCREEN_WM97XX=y
 # CONFIG_TOUCHSCREEN_WM9705 is not set
 # CONFIG_TOUCHSCREEN_WM9713 is not set
 CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_INPUT_MISC=y
+CONFIG_INPUT_GPIO_VIBRA=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_SERIAL_TEGRA=y
+CONFIG_SERIAL_DEV_BUS=y
 # CONFIG_HW_RANDOM is not set
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
@@ -131,10 +145,12 @@ CONFIG_SPI_TEGRA114=y
 CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_PINCTRL_AS3722=y
+CONFIG_PINCTRL_MAX77620=y
 CONFIG_PINCTRL_PALMAS=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
@@ -142,13 +158,21 @@ CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_AS3722=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_BATTERY_SBS=y
+CONFIG_BATTERY_BQ27XXX=y
+CONFIG_CHARGER_GPIO=y
+CONFIG_CHARGER_SMB347=y
 CONFIG_CHARGER_TPS65090=y
 CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_LM95245=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_STATISTICS=y
+CONFIG_CPU_THERMAL=y
 CONFIG_WATCHDOG=y
+CONFIG_MAX77620_WATCHDOG=y
 CONFIG_TEGRA_WATCHDOG=y
 CONFIG_MFD_AS3722=y
-CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_DEV=y
+CONFIG_MFD_MAX77620=y
 CONFIG_MFD_MAX8907=y
 CONFIG_MFD_STMPE=y
 CONFIG_MFD_PALMAS=y
@@ -159,6 +183,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_AS3722=y
 CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MAX77620=y
 CONFIG_REGULATOR_MAX8907=y
 CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_TPS51632=y
@@ -174,7 +199,10 @@ CONFIG_USB_GSPCA=y
 CONFIG_DRM=y
 CONFIG_DRM_NOUVEAU=m
 CONFIG_DRM_TEGRA=y
+CONFIG_DRM_TEGRA_STAGING=y
+CONFIG_DRM_PANEL_LVDS=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_LVDS_CODEC=y
 # CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_BACKLIGHT_GENERIC is not set
@@ -238,6 +266,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_AS3722=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_MAX8907=y
+CONFIG_RTC_DRV_MAX77686=y
 CONFIG_RTC_DRV_PALMAS=y
 CONFIG_RTC_DRV_TPS6586X=y
 CONFIG_RTC_DRV_TPS65910=y
@@ -259,11 +288,18 @@ CONFIG_ARCH_TEGRA_2x_SOC=y
 CONFIG_ARCH_TEGRA_3x_SOC=y
 CONFIG_ARCH_TEGRA_114_SOC=y
 CONFIG_ARCH_TEGRA_124_SOC=y
+CONFIG_PM_DEVFREQ=y
+CONFIG_ARM_TEGRA_DEVFREQ=y
+CONFIG_ARM_TEGRA20_DEVFREQ=y
 CONFIG_MEMORY=y
 CONFIG_IIO=y
+CONFIG_KXCJK1013=y
 CONFIG_MPU3050_I2C=y
+CONFIG_INV_MPU6050_I2C=y
+CONFIG_AL3010=y
 CONFIG_SENSORS_ISL29018=y
 CONFIG_SENSORS_ISL29028=y
+CONFIG_AK8974=y
 CONFIG_AK8975=y
 CONFIG_PWM=y
 CONFIG_PWM_TEGRA=y
@@ -282,6 +318,13 @@ CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_LZO_COMPRESS=y
+CONFIG_PSTORE_LZ4_COMPRESS=y
+CONFIG_PSTORE_LZ4HC_COMPRESS=y
+CONFIG_PSTORE_842_COMPRESS=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_RAM=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
index 10499d4..9a79ef6 100644 (file)
@@ -84,7 +84,8 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
                old = __opcode_to_mem_arm(old);
 
        if (validate) {
-               if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
+               if (copy_from_kernel_nofault(&replaced, (void *)pc,
+                               MCOUNT_INSN_SIZE))
                        return -EFAULT;
 
                if (replaced != old)
index 6a95b92..7bd30c0 100644 (file)
@@ -236,7 +236,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
        /* patch_text() only supports int-sized breakpoints */
        BUILD_BUG_ON(sizeof(int) != BREAK_INSTR_SIZE);
 
-       err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
+       err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
                                BREAK_INSTR_SIZE);
        if (err)
                return err;
index 65a3b1e..17d5a78 100644 (file)
@@ -396,7 +396,7 @@ int is_valid_bugaddr(unsigned long pc)
        u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
-       if (probe_kernel_address((unsigned *)pc, bkpt))
+       if (get_kernel_nofault(bkpt, (void *)pc))
                return 0;
 
        return bkpt == insn;
index 84718ed..81a627e 100644 (file)
@@ -774,7 +774,7 @@ static int alignment_get_arm(struct pt_regs *regs, u32 *ip, u32 *inst)
        if (user_mode(regs))
                fault = get_user(instr, ip);
        else
-               fault = probe_kernel_address(ip, instr);
+               fault = get_kernel_nofault(instr, ip);
 
        *inst = __mem_to_opcode_arm(instr);
 
@@ -789,7 +789,7 @@ static int alignment_get_thumb(struct pt_regs *regs, u16 *ip, u16 *inst)
        if (user_mode(regs))
                fault = get_user(instr, ip);
        else
-               fault = probe_kernel_address(ip, instr);
+               fault = get_kernel_nofault(instr, ip);
 
        *inst = __mem_to_opcode_thumb16(instr);
 
index 31380da..a4a094b 100644 (file)
@@ -1564,7 +1564,7 @@ config CC_HAS_SIGN_RETURN_ADDRESS
        def_bool $(cc-option,-msign-return-address=all)
 
 config AS_HAS_PAC
-       def_bool $(as-option,-Wa$(comma)-march=armv8.3-a)
+       def_bool $(cc-option,-Wa$(comma)-march=armv8.3-a)
 
 config AS_HAS_CFI_NEGATE_RA_STATE
        def_bool $(as-instr,.cfi_startproc\n.cfi_negate_ra_state\n.cfi_endproc\n)
@@ -1630,6 +1630,8 @@ config ARM64_BTI_KERNEL
        depends on CC_HAS_BRANCH_PROT_PAC_RET_BTI
        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94697
        depends on !CC_IS_GCC || GCC_VERSION >= 100100
+       # https://reviews.llvm.org/rGb8ae3fdfa579dbf366b1bb1cbfdbf8c51db7fa55
+       depends on !CC_IS_CLANG || CLANG_VERSION >= 100001
        depends on !(CC_IS_CLANG && GCOV_KERNEL)
        depends on (!FUNCTION_GRAPH_TRACER || DYNAMIC_FTRACE_WITH_REGS)
        help
index cdf7ec0..265c446 100644 (file)
@@ -8,21 +8,6 @@ config PID_IN_CONTEXTIDR
          instructions during context switch. Say Y here only if you are
          planning to use hardware trace tools with this kernel.
 
-config ARM64_RANDOMIZE_TEXT_OFFSET
-       bool "Randomize TEXT_OFFSET at build time"
-       help
-         Say Y here if you want the image load offset (AKA TEXT_OFFSET)
-         of the kernel to be randomized at build-time. When selected,
-         this option will cause TEXT_OFFSET to be randomized upon any
-         build of the kernel, and the offset will be reflected in the
-         text_offset field of the resulting Image. This can be used to
-         fuzz-test bootloaders which respect text_offset.
-
-         This option is intended for bootloader and/or kernel testing
-         only. Bootloaders must make no assumptions regarding the value
-         of TEXT_OFFSET and platforms must not require a specific
-         value.
-
 config DEBUG_EFI
        depends on EFI && DEBUG_INFO
        bool "UEFI debugging"
index 76359cf..a0d94d0 100644 (file)
@@ -121,13 +121,7 @@ endif
 head-y         := arch/arm64/kernel/head.o
 
 # The byte offset of the kernel image in RAM from the start of RAM.
-ifeq ($(CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET), y)
-TEXT_OFFSET := $(shell awk "BEGIN {srand(); printf \"0x%06x\n\", \
-                int(2 * 1024 * 1024 / (2 ^ $(CONFIG_ARM64_PAGE_SHIFT)) * \
-                rand()) * (2 ^ $(CONFIG_ARM64_PAGE_SHIFT))}")
-else
 TEXT_OFFSET := 0x0
-endif
 
 ifeq ($(CONFIG_KASAN_SW_TAGS), y)
 KASAN_SHADOW_SCALE_SHIFT := 4
index f58657a..5c16b3c 100644 (file)
@@ -161,6 +161,18 @@ CONFIG_NET_DSA=m
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
 CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_TAPRIO=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_GATE=m
 CONFIG_QRTR=m
 CONFIG_QRTR_SMD=m
 CONFIG_QRTR_TUN=m
@@ -291,6 +303,7 @@ CONFIG_FSL_DPAA_ETH=y
 CONFIG_FSL_DPAA2_ETH=y
 CONFIG_FSL_ENETC=y
 CONFIG_FSL_ENETC_VF=y
+CONFIG_FSL_ENETC_QOS=y
 CONFIG_HIX5HD2_GMAC=y
 CONFIG_HNS_DSAF=y
 CONFIG_HNS_ENET=y
@@ -309,6 +322,7 @@ CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
 CONFIG_QCOM_EMAC=m
 CONFIG_RMNET=m
+CONFIG_SH_ETH=y
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
@@ -469,6 +483,7 @@ CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_PINCTRL_SC7180=y
 CONFIG_PINCTRL_SDM845=y
 CONFIG_PINCTRL_SM8150=y
+CONFIG_PINCTRL_SM8250=y
 CONFIG_GPIO_ALTERA=m
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_MB86S7X=y
@@ -594,6 +609,8 @@ CONFIG_VIDEO_RENESAS_FCP=m
 CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_SDR_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_RCAR_DRIF=m
+CONFIG_VIDEO_IMX219=m
+CONFIG_VIDEO_OV5645=m
 CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
@@ -629,6 +646,7 @@ CONFIG_DRM_SII902X=m
 CONFIG_DRM_THINE_THC63LVD1024=m
 CONFIG_DRM_TI_SN65DSI86=m
 CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=m
 CONFIG_DRM_VC4=m
@@ -764,6 +782,7 @@ CONFIG_RTC_DRV_S3C=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_RTC_DRV_SUN6I=y
 CONFIG_RTC_DRV_ARMADA38X=y
+CONFIG_RTC_DRV_PM8XXX=m
 CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_DRV_SNVS=m
 CONFIG_RTC_DRV_IMX_SC=m
@@ -793,9 +812,12 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
-CONFIG_MFD_CROS_EC=y
+CONFIG_MFD_CROS_EC_DEV=y
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_SPI=y
+CONFIG_CROS_EC_CHARDEV=m
 CONFIG_COMMON_CLK_RK808=y
 CONFIG_COMMON_CLK_SCPI=y
 CONFIG_COMMON_CLK_CS2000_CP=y
@@ -826,6 +848,7 @@ CONFIG_SC_GCC_7180=y
 CONFIG_SDM_CAMCC_845=m
 CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
+CONFIG_SDM_VIDEOCC_845=y
 CONFIG_SDM_DISPCC_845=y
 CONFIG_SM_GCC_8150=y
 CONFIG_SM_GCC_8250=y
@@ -837,6 +860,7 @@ CONFIG_IMX_MBOX=y
 CONFIG_PLATFORM_MHU=y
 CONFIG_BCM2835_MBOX=y
 CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
 CONFIG_ROCKCHIP_IOMMU=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_ARM_SMMU=y
@@ -861,6 +885,7 @@ CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_RMTFS_MEM=m
 CONFIG_QCOM_RPMH=y
 CONFIG_QCOM_RPMHPD=y
+CONFIG_QCOM_RPMPD=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
index 6dbd267..758e2d1 100644 (file)
@@ -416,7 +416,7 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
        __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
 
 #define pgprot_nx(prot) \
-       __pgprot_modify(prot, 0, PTE_PXN)
+       __pgprot_modify(prot, PTE_MAYBE_GP, PTE_PXN)
 
 /*
  * Mark the prot value as uncacheable and unbufferable.
index 35cb5e6..55c8f3e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/bug.h>
 #include <linux/cache.h>
 #include <linux/compat.h>
+#include <linux/compiler.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
@@ -119,10 +120,20 @@ struct fpsimd_last_state_struct {
 static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
 
 /* Default VL for tasks that don't set it explicitly: */
-static int sve_default_vl = -1;
+static int __sve_default_vl = -1;
+
+static int get_sve_default_vl(void)
+{
+       return READ_ONCE(__sve_default_vl);
+}
 
 #ifdef CONFIG_ARM64_SVE
 
+static void set_sve_default_vl(int val)
+{
+       WRITE_ONCE(__sve_default_vl, val);
+}
+
 /* Maximum supported vector length across all CPUs (initially poisoned) */
 int __ro_after_init sve_max_vl = SVE_VL_MIN;
 int __ro_after_init sve_max_virtualisable_vl = SVE_VL_MIN;
@@ -338,13 +349,13 @@ static unsigned int find_supported_vector_length(unsigned int vl)
        return sve_vl_from_vq(__bit_to_vq(bit));
 }
 
-#ifdef CONFIG_SYSCTL
+#if defined(CONFIG_ARM64_SVE) && defined(CONFIG_SYSCTL)
 
 static int sve_proc_do_default_vl(struct ctl_table *table, int write,
                                  void *buffer, size_t *lenp, loff_t *ppos)
 {
        int ret;
-       int vl = sve_default_vl;
+       int vl = get_sve_default_vl();
        struct ctl_table tmp_table = {
                .data = &vl,
                .maxlen = sizeof(vl),
@@ -361,7 +372,7 @@ static int sve_proc_do_default_vl(struct ctl_table *table, int write,
        if (!sve_vl_valid(vl))
                return -EINVAL;
 
-       sve_default_vl = find_supported_vector_length(vl);
+       set_sve_default_vl(find_supported_vector_length(vl));
        return 0;
 }
 
@@ -383,9 +394,9 @@ static int __init sve_sysctl_init(void)
        return 0;
 }
 
-#else /* ! CONFIG_SYSCTL */
+#else /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
 static int __init sve_sysctl_init(void) { return 0; }
-#endif /* ! CONFIG_SYSCTL */
+#endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
 
 #define ZREG(sve_state, vq, n) ((char *)(sve_state) +          \
        (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
@@ -868,7 +879,7 @@ void __init sve_setup(void)
         * For the default VL, pick the maximum supported value <= 64.
         * VL == 64 is guaranteed not to grow the signal frame.
         */
-       sve_default_vl = find_supported_vector_length(64);
+       set_sve_default_vl(find_supported_vector_length(64));
 
        bitmap_andnot(tmp_map, sve_vq_partial_map, sve_vq_map,
                      SVE_VQ_MAX);
@@ -889,7 +900,7 @@ void __init sve_setup(void)
        pr_info("SVE: maximum available vector length %u bytes per vector\n",
                sve_max_vl);
        pr_info("SVE: default vector length %u bytes per vector\n",
-               sve_default_vl);
+               get_sve_default_vl());
 
        /* KVM decides whether to support mismatched systems. Just warn here: */
        if (sve_max_virtualisable_vl < sve_max_vl)
@@ -1029,13 +1040,13 @@ void fpsimd_flush_thread(void)
                 * vector length configured: no kernel task can become a user
                 * task without an exec and hence a call to this function.
                 * By the time the first call to this function is made, all
-                * early hardware probing is complete, so sve_default_vl
+                * early hardware probing is complete, so __sve_default_vl
                 * should be valid.
                 * If a bug causes this to go wrong, we make some noise and
                 * try to fudge thread.sve_vl to a safe value here.
                 */
                vl = current->thread.sve_vl_onexec ?
-                       current->thread.sve_vl_onexec : sve_default_vl;
+                       current->thread.sve_vl_onexec : get_sve_default_vl();
 
                if (WARN_ON(!sve_vl_valid(vl)))
                        vl = SVE_VL_MIN;
index 0b727ed..af234a1 100644 (file)
@@ -730,6 +730,27 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val,
                return 0;
 }
 
+static int watchpoint_report(struct perf_event *wp, unsigned long addr,
+                            struct pt_regs *regs)
+{
+       int step = is_default_overflow_handler(wp);
+       struct arch_hw_breakpoint *info = counter_arch_bp(wp);
+
+       info->trigger = addr;
+
+       /*
+        * If we triggered a user watchpoint from a uaccess routine, then
+        * handle the stepping ourselves since userspace really can't help
+        * us with this.
+        */
+       if (!user_mode(regs) && info->ctrl.privilege == AARCH64_BREAKPOINT_EL0)
+               step = 1;
+       else
+               perf_bp_event(wp, regs);
+
+       return step;
+}
+
 static int watchpoint_handler(unsigned long addr, unsigned int esr,
                              struct pt_regs *regs)
 {
@@ -739,7 +760,6 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
        u64 val;
        struct perf_event *wp, **slots;
        struct debug_info *debug_info;
-       struct arch_hw_breakpoint *info;
        struct arch_hw_breakpoint_ctrl ctrl;
 
        slots = this_cpu_ptr(wp_on_reg);
@@ -777,25 +797,13 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr,
                if (dist != 0)
                        continue;
 
-               info = counter_arch_bp(wp);
-               info->trigger = addr;
-               perf_bp_event(wp, regs);
-
-               /* Do we need to handle the stepping? */
-               if (is_default_overflow_handler(wp))
-                       step = 1;
+               step = watchpoint_report(wp, addr, regs);
        }
-       if (min_dist > 0 && min_dist != -1) {
-               /* No exact match found. */
-               wp = slots[closest_match];
-               info = counter_arch_bp(wp);
-               info->trigger = addr;
-               perf_bp_event(wp, regs);
 
-               /* Do we need to handle the stepping? */
-               if (is_default_overflow_handler(wp))
-                       step = 1;
-       }
+       /* No exact match found? */
+       if (min_dist > 0 && min_dist != -1)
+               step = watchpoint_report(slots[closest_match], addr, regs);
+
        rcu_read_unlock();
 
        if (!step)
index 684d871..a107375 100644 (file)
@@ -135,7 +135,7 @@ int __kprobes aarch64_insn_read(void *addr, u32 *insnp)
        int ret;
        __le32 val;
 
-       ret = probe_kernel_read(&val, addr, AARCH64_INSN_SIZE);
+       ret = copy_from_kernel_nofault(&val, addr, AARCH64_INSN_SIZE);
        if (!ret)
                *insnp = le32_to_cpu(val);
 
@@ -151,7 +151,7 @@ static int __kprobes __aarch64_insn_write(void *addr, __le32 insn)
        raw_spin_lock_irqsave(&patch_lock, flags);
        waddr = patch_map(addr, FIX_TEXT_POKE0);
 
-       ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE);
+       ret = copy_to_kernel_nofault(waddr, &insn, AARCH64_INSN_SIZE);
 
        patch_unmap(FIX_TEXT_POKE0);
        raw_spin_unlock_irqrestore(&patch_lock, flags);
index 522e6f5..361a114 100644 (file)
@@ -219,8 +219,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
                                        MEMBLOCK_NONE, &start, &end, NULL)
                nr_ranges++;
 
-       cmem = kmalloc(sizeof(struct crash_mem) +
-                       sizeof(struct crash_mem_range) * nr_ranges, GFP_KERNEL);
+       cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL);
        if (!cmem)
                return -ENOMEM;
 
index 50cc30a..47f651d 100644 (file)
@@ -376,7 +376,7 @@ static int call_undef_hook(struct pt_regs *regs)
 
        if (!user_mode(regs)) {
                __le32 instr_le;
-               if (probe_kernel_address((__force __le32 *)pc, instr_le))
+               if (get_kernel_nofault(instr_le, (__force __le32 *)pc))
                        goto exit;
                instr = le32_to_cpu(instr_le);
        } else if (compat_thumb_mode(regs)) {
@@ -813,6 +813,7 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
                handler[reason], smp_processor_id(), esr,
                esr_get_class_string(esr));
 
+       __show_regs(regs);
        local_daif_mask();
        panic("bad mode");
 }
index e631e64..1e93cfc 100644 (file)
@@ -404,11 +404,6 @@ void __init arm64_memblock_init(void)
        high_memory = __va(memblock_end_of_DRAM() - 1) + 1;
 
        dma_contiguous_reserve(arm64_dma32_phys_limit);
-
-#ifdef CONFIG_ARM64_4K_PAGES
-       hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
-#endif
-
 }
 
 void __init bootmem_init(void)
@@ -424,6 +419,16 @@ void __init bootmem_init(void)
        min_low_pfn = min;
 
        arm64_numa_init();
+
+       /*
+        * must be done after arm64_numa_init() which calls numa_init() to
+        * initialize node_online_map that gets used in hugetlb_cma_reserve()
+        * while allocating required CMA size across online nodes.
+        */
+#ifdef CONFIG_ARM64_4K_PAGES
+       hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT);
+#endif
+
        /*
         * Sparsemem tries to allocate bootmem in memory_present(), so must be
         * done after the fixed reservations.
index 990929c..1df25f2 100644 (file)
@@ -723,6 +723,7 @@ int kern_addr_valid(unsigned long addr)
        pmd_t *pmdp, pmd;
        pte_t *ptep, pte;
 
+       addr = arch_kasan_reset_tag(addr);
        if ((((long)addr) >> VA_BITS) != -1UL)
                return 0;
 
index 3c425b8..b4a7ec1 100644 (file)
@@ -72,7 +72,8 @@ static int ftrace_check_current_nop(unsigned long hook)
        uint16_t olds[7];
        unsigned long hook_pos = hook - 2;
 
-       if (probe_kernel_read((void *)olds, (void *)hook_pos, sizeof(nops)))
+       if (copy_from_kernel_nofault((void *)olds, (void *)hook_pos,
+                       sizeof(nops)))
                return -EFAULT;
 
        if (memcmp((void *)nops, (void *)olds, sizeof(nops))) {
@@ -97,7 +98,7 @@ static int ftrace_modify_code(unsigned long hook, unsigned long target,
 
        make_jbsr(target, hook, call, nolr);
 
-       ret = probe_kernel_write((void *)hook_pos, enable ? call : nops,
+       ret = copy_to_kernel_nofault((void *)hook_pos, enable ? call : nops,
                                 sizeof(nops));
        if (ret)
                return -EPERM;
index cea15f2..3a033d2 100644 (file)
@@ -35,7 +35,7 @@ static inline void *dereference_function_descriptor(void *ptr)
        struct fdesc *desc = ptr;
        void *p;
 
-       if (!probe_kernel_address(&desc->ip, p))
+       if (!get_kernel_nofault(p, (void *)&desc->ip))
                ptr = p;
        return ptr;
 }
index cee411e..b2ab2d5 100644 (file)
@@ -108,7 +108,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
                goto skip_check;
 
        /* read the text we want to modify */
-       if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
                return -EFAULT;
 
        /* Make sure it is what we expect it to be */
@@ -117,7 +117,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
 
 skip_check:
        /* replace the text with the new text */
-       if (probe_kernel_write(((void *)ip), new_code, MCOUNT_INSN_SIZE))
+       if (copy_to_kernel_nofault(((void *)ip), new_code, MCOUNT_INSN_SIZE))
                return -EPERM;
        flush_icache_range(ip, ip + MCOUNT_INSN_SIZE);
 
@@ -129,7 +129,7 @@ static int ftrace_make_nop_check(struct dyn_ftrace *rec, unsigned long addr)
        unsigned char __attribute__((aligned(8))) replaced[MCOUNT_INSN_SIZE];
        unsigned long ip = rec->ip;
 
-       if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
                return -EFAULT;
        if (rec->flags & FTRACE_FL_CONVERTED) {
                struct ftrace_call_insn *call_insn, *tmp_call;
index 67994a7..1dd57ba 100644 (file)
@@ -42,7 +42,7 @@ enum unw_register_index {
 
 struct unw_info_block {
        u64 header;
-       u64 desc[0];            /* unwind descriptors */
+       u64 desc[];             /* unwind descriptors */
        /* personality routine and language-specific data follow behind descriptors */
 };
 
index 6cfae24..d043c2f 100644 (file)
@@ -86,9 +86,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
                goto out;
        }
 
-       if ((probe_kernel_read(&prev_insn, p->addr - 1,
-                               sizeof(mips_instruction)) == 0) &&
-                               insn_has_delayslot(prev_insn)) {
+       if (copy_from_kernel_nofault(&prev_insn, p->addr - 1,
+                       sizeof(mips_instruction)) == 0 &&
+           insn_has_delayslot(prev_insn)) {
                pr_notice("Kprobes for branch delayslot are not supported\n");
                ret = -EINVAL;
                goto out;
index 22ab77e..3763b3f 100644 (file)
@@ -131,13 +131,14 @@ static int __ftrace_modify_code(unsigned long pc, unsigned long *old_insn,
        unsigned long orig_insn[3];
 
        if (validate) {
-               if (probe_kernel_read(orig_insn, (void *)pc, MCOUNT_INSN_SIZE))
+               if (copy_from_kernel_nofault(orig_insn, (void *)pc,
+                               MCOUNT_INSN_SIZE))
                        return -EFAULT;
                if (memcmp(orig_insn, old_insn, MCOUNT_INSN_SIZE))
                        return -EINVAL;
        }
 
-       if (probe_kernel_write((void *)pc, new_insn, MCOUNT_INSN_SIZE))
+       if (copy_to_kernel_nofault((void *)pc, new_insn, MCOUNT_INSN_SIZE))
                return -EPERM;
 
        return 0;
index b836fc6..1df0f67 100644 (file)
@@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
        ip = (void *)(rec->ip + 4 - size);
 
-       ret = probe_kernel_read(insn, ip, size);
+       ret = copy_from_kernel_nofault(insn, ip, size);
        if (ret)
                return ret;
 
index 664278d..c4554ac 100644 (file)
@@ -154,8 +154,8 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
 
 int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 {
-       int ret = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
-                               BREAK_INSTR_SIZE);
+       int ret = copy_from_kernel_nofault(bpt->saved_instr,
+                       (char *)bpt->bpt_addr, BREAK_INSTR_SIZE);
        if (ret)
                return ret;
 
index 230a642..b7abb12 100644 (file)
@@ -293,7 +293,7 @@ void *dereference_function_descriptor(void *ptr)
        Elf64_Fdesc *desc = ptr;
        void *p;
 
-       if (!probe_kernel_address(&desc->addr, p))
+       if (!get_kernel_nofault(p, (void *)&desc->addr))
                ptr = p;
        return ptr;
 }
index 94a9fe2..4b75388 100644 (file)
@@ -57,7 +57,7 @@ void * memcpy(void * dst,const void *src, size_t count)
 EXPORT_SYMBOL(raw_copy_in_user);
 EXPORT_SYMBOL(memcpy);
 
-bool probe_kernel_read_allowed(const void *unsafe_src, size_t size)
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
 {
        if ((unsigned long)unsafe_src < PAGE_SIZE)
                return false;
index b56f141..b0afbdd 100644 (file)
@@ -205,10 +205,6 @@ static inline void pmd_clear(pmd_t *pmdp)
        *pmdp = __pmd(0);
 }
 
-/* to find an entry in a page-table-directory */
-#define pgd_index(address)      ((address) >> PGDIR_SHIFT)
-#define pgd_offset(mm, address)         ((mm)->pgd + pgd_index(address))
-
 /*
  * PTE updates. This function is called whenever an existing
  * valid PTE is updated. This does -not- include set_pte_at()
@@ -230,6 +226,8 @@ static inline void pmd_clear(pmd_t *pmdp)
  * For other page sizes, we have a single entry in the table.
  */
 #ifdef CONFIG_PPC_8xx
+static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr);
+
 static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
                                     unsigned long clr, unsigned long set, int huge)
 {
@@ -237,7 +235,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
        pte_basic_t old = pte_val(*p);
        pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
        int num, i;
-       pmd_t *pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), addr), addr);
+       pmd_t *pmd = pmd_off(mm, addr);
 
        if (!huge)
                num = PAGE_SIZE / SZ_4K;
@@ -286,6 +284,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
        return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
 }
 
+#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
+#define __HAVE_ARCH_PTEP_GET
+static inline pte_t ptep_get(pte_t *ptep)
+{
+       pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
+
+       return pte;
+}
+#endif
+
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
                                      pte_t *ptep)
index d198717..324d7b2 100644 (file)
@@ -85,7 +85,7 @@ static inline void *dereference_function_descriptor(void *ptr)
        struct ppc64_opd_entry *desc = ptr;
        void *p;
 
-       if (!probe_kernel_address(&desc->funcaddr, p))
+       if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
                ptr = p;
        return ptr;
 }
diff --git a/arch/powerpc/include/uapi/asm/papr_pdsm.h b/arch/powerpc/include/uapi/asm/papr_pdsm.h
new file mode 100644 (file)
index 0000000..9ccecc1
--- /dev/null
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * PAPR nvDimm Specific Methods (PDSM) and structs for libndctl
+ *
+ * (C) Copyright IBM 2020
+ *
+ * Author: Vaibhav Jain <vaibhav at linux.ibm.com>
+ */
+
+#ifndef _UAPI_ASM_POWERPC_PAPR_PDSM_H_
+#define _UAPI_ASM_POWERPC_PAPR_PDSM_H_
+
+#include <linux/types.h>
+#include <linux/ndctl.h>
+
+/*
+ * PDSM Envelope:
+ *
+ * The ioctl ND_CMD_CALL exchange data between user-space and kernel via
+ * envelope which consists of 2 headers sections and payload sections as
+ * illustrated below:
+ *  +-----------------+---------------+---------------------------+
+ *  |   64-Bytes      |   8-Bytes     |       Max 184-Bytes       |
+ *  +-----------------+---------------+---------------------------+
+ *  | ND-HEADER       |  PDSM-HEADER  |      PDSM-PAYLOAD         |
+ *  +-----------------+---------------+---------------------------+
+ *  | nd_family       |               |                           |
+ *  | nd_size_out     | cmd_status    |                           |
+ *  | nd_size_in      | reserved      |     nd_pdsm_payload       |
+ *  | nd_command      | payload   --> |                           |
+ *  | nd_fw_size      |               |                           |
+ *  | nd_payload ---> |               |                           |
+ *  +---------------+-----------------+---------------------------+
+ *
+ * ND Header:
+ * This is the generic libnvdimm header described as 'struct nd_cmd_pkg'
+ * which is interpreted by libnvdimm before passed on to papr_scm. Important
+ * member fields used are:
+ * 'nd_family'         : (In) NVDIMM_FAMILY_PAPR_SCM
+ * 'nd_size_in'                : (In) PDSM-HEADER + PDSM-IN-PAYLOAD (usually 0)
+ * 'nd_size_out'        : (In) PDSM-HEADER + PDSM-RETURN-PAYLOAD
+ * 'nd_command'         : (In) One of PAPR_PDSM_XXX
+ * 'nd_fw_size'         : (Out) PDSM-HEADER + size of actual payload returned
+ *
+ * PDSM Header:
+ * This is papr-scm specific header that precedes the payload. This is defined
+ * as nd_cmd_pdsm_pkg.  Following fields aare available in this header:
+ *
+ * 'cmd_status'                : (Out) Errors if any encountered while servicing PDSM.
+ * 'reserved'          : Not used, reserved for future and should be set to 0.
+ * 'payload'            : A union of all the possible payload structs
+ *
+ * PDSM Payload:
+ *
+ * The layout of the PDSM Payload is defined by various structs shared between
+ * papr_scm and libndctl so that contents of payload can be interpreted. As such
+ * its defined as a union of all possible payload structs as
+ * 'union nd_pdsm_payload'. Based on the value of 'nd_cmd_pkg.nd_command'
+ * appropriate member of the union is accessed.
+ */
+
+/* Max payload size that we can handle */
+#define ND_PDSM_PAYLOAD_MAX_SIZE 184
+
+/* Max payload size that we can handle */
+#define ND_PDSM_HDR_SIZE \
+       (sizeof(struct nd_pkg_pdsm) - ND_PDSM_PAYLOAD_MAX_SIZE)
+
+/* Various nvdimm health indicators */
+#define PAPR_PDSM_DIMM_HEALTHY       0
+#define PAPR_PDSM_DIMM_UNHEALTHY     1
+#define PAPR_PDSM_DIMM_CRITICAL      2
+#define PAPR_PDSM_DIMM_FATAL         3
+
+/*
+ * Struct exchanged between kernel & ndctl in for PAPR_PDSM_HEALTH
+ * Various flags indicate the health status of the dimm.
+ *
+ * extension_flags     : Any extension fields present in the struct.
+ * dimm_unarmed                : Dimm not armed. So contents wont persist.
+ * dimm_bad_shutdown   : Previous shutdown did not persist contents.
+ * dimm_bad_restore    : Contents from previous shutdown werent restored.
+ * dimm_scrubbed       : Contents of the dimm have been scrubbed.
+ * dimm_locked         : Contents of the dimm cant be modified until CEC reboot
+ * dimm_encrypted      : Contents of dimm are encrypted.
+ * dimm_health         : Dimm health indicator. One of PAPR_PDSM_DIMM_XXXX
+ */
+struct nd_papr_pdsm_health {
+       union {
+               struct {
+                       __u32 extension_flags;
+                       __u8 dimm_unarmed;
+                       __u8 dimm_bad_shutdown;
+                       __u8 dimm_bad_restore;
+                       __u8 dimm_scrubbed;
+                       __u8 dimm_locked;
+                       __u8 dimm_encrypted;
+                       __u16 dimm_health;
+               };
+               __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+       };
+};
+
+/*
+ * Methods to be embedded in ND_CMD_CALL request. These are sent to the kernel
+ * via 'nd_cmd_pkg.nd_command' member of the ioctl struct
+ */
+enum papr_pdsm {
+       PAPR_PDSM_MIN = 0x0,
+       PAPR_PDSM_HEALTH,
+       PAPR_PDSM_MAX,
+};
+
+/* Maximal union that can hold all possible payload types */
+union nd_pdsm_payload {
+       struct nd_papr_pdsm_health health;
+       __u8 buf[ND_PDSM_PAYLOAD_MAX_SIZE];
+} __packed;
+
+/*
+ * PDSM-header + payload expected with ND_CMD_CALL ioctl from libnvdimm
+ * Valid member of union 'payload' is identified via 'nd_cmd_pkg.nd_command'
+ * that should always precede this struct when sent to papr_scm via CMD_CALL
+ * interface.
+ */
+struct nd_pkg_pdsm {
+       __s32 cmd_status;       /* Out: Sub-cmd status returned back */
+       __u16 reserved[2];      /* Ignored and to be set as '0' */
+       union nd_pdsm_payload payload;
+} __packed;
+
+#endif /* _UAPI_ASM_POWERPC_PAPR_PDSM_H_ */
index e70ebb5..fa08069 100644 (file)
@@ -270,7 +270,7 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
        .endif
 
-       ld      r10,PACA_EXGEN+EX_CTR(r13)
+       ld      r10,IAREA+EX_CTR(r13)
        mtctr   r10
 BEGIN_FTR_SECTION
        ld      r10,IAREA+EX_PPR(r13)
@@ -298,7 +298,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
        .if IKVM_SKIP
 89:    mtocrf  0x80,r9
-       ld      r10,PACA_EXGEN+EX_CTR(r13)
+       ld      r10,IAREA+EX_CTR(r13)
        mtctr   r10
        ld      r9,IAREA+EX_R9(r13)
        ld      r10,IAREA+EX_R10(r13)
index 652b285..4090802 100644 (file)
@@ -421,7 +421,7 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
        unsigned int instr;
        struct ppc_inst *addr = (struct ppc_inst *)bpt->bpt_addr;
 
-       err = probe_kernel_address(addr, instr);
+       err = get_kernel_nofault(instr, (unsigned *) addr);
        if (err)
                return err;
 
index 6f96f65..9cc792a 100644 (file)
@@ -289,7 +289,7 @@ int kprobe_handler(struct pt_regs *regs)
        if (!p) {
                unsigned int instr;
 
-               if (probe_kernel_address(addr, instr))
+               if (get_kernel_nofault(instr, addr))
                        goto no_kprobe;
 
                if (instr != BREAKPOINT_INSTRUCTION) {
index f4c2fa1..ae2b188 100644 (file)
@@ -756,7 +756,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr,
 
        stub = (struct ppc64_stub_entry *)addr;
 
-       if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) {
+       if (copy_from_kernel_nofault(&magic, &stub->magic,
+                       sizeof(magic))) {
                pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name);
                return -EFAULT;
        }
@@ -766,7 +767,8 @@ int module_trampoline_target(struct module *mod, unsigned long addr,
                return -EFAULT;
        }
 
-       if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) {
+       if (copy_from_kernel_nofault(&funcdata, &stub->funcdata,
+                       sizeof(funcdata))) {
                pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name);
                 return -EFAULT;
        }
index 7bb7faf..4650b9b 100644 (file)
@@ -1252,29 +1252,31 @@ struct task_struct *__switch_to(struct task_struct *prev,
 static void show_instructions(struct pt_regs *regs)
 {
        int i;
+       unsigned long nip = regs->nip;
        unsigned long pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));
 
        printk("Instruction dump:");
 
+       /*
+        * If we were executing with the MMU off for instructions, adjust pc
+        * rather than printing XXXXXXXX.
+        */
+       if (!IS_ENABLED(CONFIG_BOOKE) && !(regs->msr & MSR_IR)) {
+               pc = (unsigned long)phys_to_virt(pc);
+               nip = (unsigned long)phys_to_virt(regs->nip);
+       }
+
        for (i = 0; i < NR_INSN_TO_PRINT; i++) {
                int instr;
 
                if (!(i % 8))
                        pr_cont("\n");
 
-#if !defined(CONFIG_BOOKE)
-               /* If executing with the IMMU off, adjust pc rather
-                * than print XXXXXXXX.
-                */
-               if (!(regs->msr & MSR_IR))
-                       pc = (unsigned long)phys_to_virt(pc);
-#endif
-
                if (!__kernel_text_address(pc) ||
-                   probe_kernel_address((const void *)pc, instr)) {
+                   get_kernel_nofault(instr, (const void *)pc)) {
                        pr_cont("XXXXXXXX ");
                } else {
-                       if (regs->nip == pc)
+                       if (nip == pc)
                                pr_cont("<%08x> ", instr);
                        else
                                pr_cont("%08x ", instr);
@@ -1305,7 +1307,8 @@ void show_user_instructions(struct pt_regs *regs)
                for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) {
                        int instr;
 
-                       if (probe_user_read(&instr, (void __user *)pc, sizeof(instr))) {
+                       if (copy_from_user_nofault(&instr, (void __user *)pc,
+                                       sizeof(instr))) {
                                seq_buf_printf(&s, "XXXXXXXX ");
                                continue;
                        }
index 5e39962..c1fede6 100644 (file)
@@ -226,7 +226,7 @@ __ftrace_make_nop(struct module *mod,
        unsigned long ip = rec->ip;
        unsigned long tramp;
 
-       if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(&op, (void *)ip, MCOUNT_INSN_SIZE))
                return -EFAULT;
 
        /* Make sure that that this is still a 24bit jump */
@@ -249,7 +249,7 @@ __ftrace_make_nop(struct module *mod,
        pr_devel("ip:%lx jumps to %lx", ip, tramp);
 
        /* Find where the trampoline jumps to */
-       if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
+       if (copy_from_kernel_nofault(jmp, (void *)tramp, sizeof(jmp))) {
                pr_err("Failed to read %lx\n", tramp);
                return -EFAULT;
        }
index 3cb0c98..e738ea6 100644 (file)
@@ -64,9 +64,9 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
        isync();
 
        if (is_load)
-               ret = probe_user_read(to, (const void __user *)from, n);
+               ret = copy_from_user_nofault(to, (const void __user *)from, n);
        else
-               ret = probe_user_write((void __user *)to, from, n);
+               ret = copy_to_user_nofault((void __user *)to, from, n);
 
        /* switch the pid first to avoid running host with unallocated pid */
        if (quadrant == 1 && pid != old_pid)
index aedfd6e..9cc17eb 100644 (file)
@@ -15,11 +15,11 @@ int probe_user_read_inst(struct ppc_inst *inst,
        unsigned int val, suffix;
        int err;
 
-       err = probe_user_read(&val, nip, sizeof(val));
+       err = copy_from_user_nofault(&val, nip, sizeof(val));
        if (err)
                return err;
        if (get_op(val) == OP_PREFIX) {
-               err = probe_user_read(&suffix, (void __user *)nip + 4, 4);
+               err = copy_from_user_nofault(&suffix, (void __user *)nip + 4, 4);
                *inst = ppc_inst_prefix(val, suffix);
        } else {
                *inst = ppc_inst(val);
@@ -33,11 +33,11 @@ int probe_kernel_read_inst(struct ppc_inst *inst,
        unsigned int val, suffix;
        int err;
 
-       err = probe_kernel_read(&val, src, sizeof(val));
+       err = copy_from_kernel_nofault(&val, src, sizeof(val));
        if (err)
                return err;
        if (get_op(val) == OP_PREFIX) {
-               err = probe_kernel_read(&suffix, (void *)src + 4, 4);
+               err = copy_from_kernel_nofault(&suffix, (void *)src + 4, 4);
                *inst = ppc_inst_prefix(val, suffix);
        } else {
                *inst = ppc_inst(val);
@@ -51,7 +51,7 @@ int probe_user_read_inst(struct ppc_inst *inst,
        unsigned int val;
        int err;
 
-       err = probe_user_read(&val, nip, sizeof(val));
+       err = copy_from_user_nofault(&val, nip, sizeof(val));
        if (!err)
                *inst = ppc_inst(val);
 
@@ -64,7 +64,7 @@ int probe_kernel_read_inst(struct ppc_inst *inst,
        unsigned int val;
        int err;
 
-       err = probe_kernel_read(&val, src, sizeof(val));
+       err = copy_from_kernel_nofault(&val, src, sizeof(val));
        if (!err)
                *inst = ppc_inst(val);
 
index 6f347fa..9db7ada 100644 (file)
@@ -33,7 +33,8 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
         * which means that we've done all that we can do from
         * interrupt context.
         */
-       if (probe_user_read(stack_frame, (void __user *)p, sizeof(stack_frame)))
+       if (copy_from_user_nofault(stack_frame, (void __user *)p,
+                       sizeof(stack_frame)))
                return 0;
 
        if (!is_first)
@@ -51,7 +52,8 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
 {
        unsigned long stack_frame[3];
 
-       if (probe_user_read(stack_frame, (void __user *)sp, sizeof(stack_frame)))
+       if (copy_from_user_nofault(stack_frame, (void __user *)sp,
+                       sizeof(stack_frame)))
                return 0;
 
        if (!is_first)
index f7d888d..542e68b 100644 (file)
@@ -44,7 +44,7 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
            ((unsigned long)ptr & 3))
                return -EFAULT;
 
-       rc = probe_user_read(ret, ptr, sizeof(*ret));
+       rc = copy_from_user_nofault(ret, ptr, sizeof(*ret));
 
        if (IS_ENABLED(CONFIG_PPC64) && rc)
                return read_user_stack_slow(ptr, ret, 4);
index 814d1c2..fa2a1b8 100644 (file)
@@ -50,7 +50,7 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
            ((unsigned long)ptr & 7))
                return -EFAULT;
 
-       if (!probe_user_read(ret, ptr, sizeof(*ret)))
+       if (!copy_from_user_nofault(ret, ptr, sizeof(*ret)))
                return 0;
 
        return read_user_stack_slow(ptr, ret, 8);
index 13b9dd5..cd6a742 100644 (file)
@@ -418,14 +418,16 @@ static __u64 power_pmu_bhrb_to(u64 addr)
        __u64 target;
 
        if (is_kernel_addr(addr)) {
-               if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
+               if (copy_from_kernel_nofault(&instr, (void *)addr,
+                               sizeof(instr)))
                        return 0;
 
                return branch_target((struct ppc_inst *)&instr);
        }
 
        /* Userspace: need copy instruction here then translate it */
-       if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr)))
+       if (copy_from_user_nofault(&instr, (unsigned int __user *)addr,
+                       sizeof(instr)))
                return 0;
 
        target = branch_target((struct ppc_inst *)&instr);
index cbee366..abdef9b 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 static void *spu_syscall_table[] = {
-#define __SYSCALL(nr, entry)   entry,
+#define __SYSCALL(nr, entry) [nr] = entry,
 #include <asm/syscall_table_spu.h>
 #undef __SYSCALL
 };
index f355924..9c56907 100644 (file)
 #include <linux/libnvdimm.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
+#include <linux/seq_buf.h>
 
 #include <asm/plpar_wrappers.h>
+#include <asm/papr_pdsm.h>
 
 #define BIND_ANY_ADDR (~0ul)
 
 #define PAPR_SCM_DIMM_CMD_MASK \
        ((1ul << ND_CMD_GET_CONFIG_SIZE) | \
         (1ul << ND_CMD_GET_CONFIG_DATA) | \
-        (1ul << ND_CMD_SET_CONFIG_DATA))
-
+        (1ul << ND_CMD_SET_CONFIG_DATA) | \
+        (1ul << ND_CMD_CALL))
+
+/* DIMM health bitmap bitmap indicators */
+/* SCM device is unable to persist memory contents */
+#define PAPR_PMEM_UNARMED                   (1ULL << (63 - 0))
+/* SCM device failed to persist memory contents */
+#define PAPR_PMEM_SHUTDOWN_DIRTY            (1ULL << (63 - 1))
+/* SCM device contents are persisted from previous IPL */
+#define PAPR_PMEM_SHUTDOWN_CLEAN            (1ULL << (63 - 2))
+/* SCM device contents are not persisted from previous IPL */
+#define PAPR_PMEM_EMPTY                     (1ULL << (63 - 3))
+/* SCM device memory life remaining is critically low */
+#define PAPR_PMEM_HEALTH_CRITICAL           (1ULL << (63 - 4))
+/* SCM device will be garded off next IPL due to failure */
+#define PAPR_PMEM_HEALTH_FATAL              (1ULL << (63 - 5))
+/* SCM contents cannot persist due to current platform health status */
+#define PAPR_PMEM_HEALTH_UNHEALTHY          (1ULL << (63 - 6))
+/* SCM device is unable to persist memory contents in certain conditions */
+#define PAPR_PMEM_HEALTH_NON_CRITICAL       (1ULL << (63 - 7))
+/* SCM device is encrypted */
+#define PAPR_PMEM_ENCRYPTED                 (1ULL << (63 - 8))
+/* SCM device has been scrubbed and locked */
+#define PAPR_PMEM_SCRUBBED_AND_LOCKED       (1ULL << (63 - 9))
+
+/* Bits status indicators for health bitmap indicating unarmed dimm */
+#define PAPR_PMEM_UNARMED_MASK (PAPR_PMEM_UNARMED |            \
+                               PAPR_PMEM_HEALTH_UNHEALTHY)
+
+/* Bits status indicators for health bitmap indicating unflushed dimm */
+#define PAPR_PMEM_BAD_SHUTDOWN_MASK (PAPR_PMEM_SHUTDOWN_DIRTY)
+
+/* Bits status indicators for health bitmap indicating unrestored dimm */
+#define PAPR_PMEM_BAD_RESTORE_MASK  (PAPR_PMEM_EMPTY)
+
+/* Bit status indicators for smart event notification */
+#define PAPR_PMEM_SMART_EVENT_MASK (PAPR_PMEM_HEALTH_CRITICAL | \
+                                   PAPR_PMEM_HEALTH_FATAL |    \
+                                   PAPR_PMEM_HEALTH_UNHEALTHY)
+
+/* private struct associated with each region */
 struct papr_scm_priv {
        struct platform_device *pdev;
        struct device_node *dn;
@@ -39,6 +80,15 @@ struct papr_scm_priv {
        struct resource res;
        struct nd_region *region;
        struct nd_interleave_set nd_set;
+
+       /* Protect dimm health data from concurrent read/writes */
+       struct mutex health_mutex;
+
+       /* Last time the health information of the dimm was updated */
+       unsigned long lasthealth_jiffies;
+
+       /* Health information for the dimm */
+       u64 health_bitmap;
 };
 
 static int drc_pmem_bind(struct papr_scm_priv *p)
@@ -144,6 +194,61 @@ err_out:
        return drc_pmem_bind(p);
 }
 
+/*
+ * Issue hcall to retrieve dimm health info and populate papr_scm_priv with the
+ * health information.
+ */
+static int __drc_pmem_query_health(struct papr_scm_priv *p)
+{
+       unsigned long ret[PLPAR_HCALL_BUFSIZE];
+       long rc;
+
+       /* issue the hcall */
+       rc = plpar_hcall(H_SCM_HEALTH, ret, p->drc_index);
+       if (rc != H_SUCCESS) {
+               dev_err(&p->pdev->dev,
+                       "Failed to query health information, Err:%ld\n", rc);
+               return -ENXIO;
+       }
+
+       p->lasthealth_jiffies = jiffies;
+       p->health_bitmap = ret[0] & ret[1];
+
+       dev_dbg(&p->pdev->dev,
+               "Queried dimm health info. Bitmap:0x%016lx Mask:0x%016lx\n",
+               ret[0], ret[1]);
+
+       return 0;
+}
+
+/* Min interval in seconds for assuming stable dimm health */
+#define MIN_HEALTH_QUERY_INTERVAL 60
+
+/* Query cached health info and if needed call drc_pmem_query_health */
+static int drc_pmem_query_health(struct papr_scm_priv *p)
+{
+       unsigned long cache_timeout;
+       int rc;
+
+       /* Protect concurrent modifications to papr_scm_priv */
+       rc = mutex_lock_interruptible(&p->health_mutex);
+       if (rc)
+               return rc;
+
+       /* Jiffies offset for which the health data is assumed to be same */
+       cache_timeout = p->lasthealth_jiffies +
+               msecs_to_jiffies(MIN_HEALTH_QUERY_INTERVAL * 1000);
+
+       /* Fetch new health info is its older than MIN_HEALTH_QUERY_INTERVAL */
+       if (time_after(jiffies, cache_timeout))
+               rc = __drc_pmem_query_health(p);
+       else
+               /* Assume cached health data is valid */
+               rc = 0;
+
+       mutex_unlock(&p->health_mutex);
+       return rc;
+}
 
 static int papr_scm_meta_get(struct papr_scm_priv *p,
                             struct nd_cmd_get_config_data_hdr *hdr)
@@ -246,16 +351,250 @@ static int papr_scm_meta_set(struct papr_scm_priv *p,
        return 0;
 }
 
+/*
+ * Do a sanity checks on the inputs args to dimm-control function and return
+ * '0' if valid. Validation of PDSM payloads happens later in
+ * papr_scm_service_pdsm.
+ */
+static int is_cmd_valid(struct nvdimm *nvdimm, unsigned int cmd, void *buf,
+                       unsigned int buf_len)
+{
+       unsigned long cmd_mask = PAPR_SCM_DIMM_CMD_MASK;
+       struct nd_cmd_pkg *nd_cmd;
+       struct papr_scm_priv *p;
+       enum papr_pdsm pdsm;
+
+       /* Only dimm-specific calls are supported atm */
+       if (!nvdimm)
+               return -EINVAL;
+
+       /* get the provider data from struct nvdimm */
+       p = nvdimm_provider_data(nvdimm);
+
+       if (!test_bit(cmd, &cmd_mask)) {
+               dev_dbg(&p->pdev->dev, "Unsupported cmd=%u\n", cmd);
+               return -EINVAL;
+       }
+
+       /* For CMD_CALL verify pdsm request */
+       if (cmd == ND_CMD_CALL) {
+               /* Verify the envelope and envelop size */
+               if (!buf ||
+                   buf_len < (sizeof(struct nd_cmd_pkg) + ND_PDSM_HDR_SIZE)) {
+                       dev_dbg(&p->pdev->dev, "Invalid pkg size=%u\n",
+                               buf_len);
+                       return -EINVAL;
+               }
+
+               /* Verify that the nd_cmd_pkg.nd_family is correct */
+               nd_cmd = (struct nd_cmd_pkg *)buf;
+
+               if (nd_cmd->nd_family != NVDIMM_FAMILY_PAPR) {
+                       dev_dbg(&p->pdev->dev, "Invalid pkg family=0x%llx\n",
+                               nd_cmd->nd_family);
+                       return -EINVAL;
+               }
+
+               pdsm = (enum papr_pdsm)nd_cmd->nd_command;
+
+               /* Verify if the pdsm command is valid */
+               if (pdsm <= PAPR_PDSM_MIN || pdsm >= PAPR_PDSM_MAX) {
+                       dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid PDSM\n",
+                               pdsm);
+                       return -EINVAL;
+               }
+
+               /* Have enough space to hold returned 'nd_pkg_pdsm' header */
+               if (nd_cmd->nd_size_out < ND_PDSM_HDR_SIZE) {
+                       dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid payload\n",
+                               pdsm);
+                       return -EINVAL;
+               }
+       }
+
+       /* Let the command be further processed */
+       return 0;
+}
+
+/* Fetch the DIMM health info and populate it in provided package. */
+static int papr_pdsm_health(struct papr_scm_priv *p,
+                           union nd_pdsm_payload *payload)
+{
+       int rc;
+
+       /* Ensure dimm health mutex is taken preventing concurrent access */
+       rc = mutex_lock_interruptible(&p->health_mutex);
+       if (rc)
+               goto out;
+
+       /* Always fetch upto date dimm health data ignoring cached values */
+       rc = __drc_pmem_query_health(p);
+       if (rc) {
+               mutex_unlock(&p->health_mutex);
+               goto out;
+       }
+
+       /* update health struct with various flags derived from health bitmap */
+       payload->health = (struct nd_papr_pdsm_health) {
+               .extension_flags = 0,
+               .dimm_unarmed = !!(p->health_bitmap & PAPR_PMEM_UNARMED_MASK),
+               .dimm_bad_shutdown = !!(p->health_bitmap & PAPR_PMEM_BAD_SHUTDOWN_MASK),
+               .dimm_bad_restore = !!(p->health_bitmap & PAPR_PMEM_BAD_RESTORE_MASK),
+               .dimm_scrubbed = !!(p->health_bitmap & PAPR_PMEM_SCRUBBED_AND_LOCKED),
+               .dimm_locked = !!(p->health_bitmap & PAPR_PMEM_SCRUBBED_AND_LOCKED),
+               .dimm_encrypted = !!(p->health_bitmap & PAPR_PMEM_ENCRYPTED),
+               .dimm_health = PAPR_PDSM_DIMM_HEALTHY,
+       };
+
+       /* Update field dimm_health based on health_bitmap flags */
+       if (p->health_bitmap & PAPR_PMEM_HEALTH_FATAL)
+               payload->health.dimm_health = PAPR_PDSM_DIMM_FATAL;
+       else if (p->health_bitmap & PAPR_PMEM_HEALTH_CRITICAL)
+               payload->health.dimm_health = PAPR_PDSM_DIMM_CRITICAL;
+       else if (p->health_bitmap & PAPR_PMEM_HEALTH_UNHEALTHY)
+               payload->health.dimm_health = PAPR_PDSM_DIMM_UNHEALTHY;
+
+       /* struct populated hence can release the mutex now */
+       mutex_unlock(&p->health_mutex);
+       rc = sizeof(struct nd_papr_pdsm_health);
+
+out:
+       return rc;
+}
+
+/*
+ * 'struct pdsm_cmd_desc'
+ * Identifies supported PDSMs' expected length of in/out payloads
+ * and pdsm service function.
+ *
+ * size_in     : Size of input payload if any in the PDSM request.
+ * size_out    : Size of output payload if any in the PDSM request.
+ * service     : Service function for the PDSM request. Return semantics:
+ *               rc < 0 : Error servicing PDSM and rc indicates the error.
+ *               rc >=0 : Serviced successfully and 'rc' indicate number of
+ *                     bytes written to payload.
+ */
+struct pdsm_cmd_desc {
+       u32 size_in;
+       u32 size_out;
+       int (*service)(struct papr_scm_priv *dimm,
+                      union nd_pdsm_payload *payload);
+};
+
+/* Holds all supported PDSMs' command descriptors */
+static const struct pdsm_cmd_desc __pdsm_cmd_descriptors[] = {
+       [PAPR_PDSM_MIN] = {
+               .size_in = 0,
+               .size_out = 0,
+               .service = NULL,
+       },
+       /* New PDSM command descriptors to be added below */
+
+       [PAPR_PDSM_HEALTH] = {
+               .size_in = 0,
+               .size_out = sizeof(struct nd_papr_pdsm_health),
+               .service = papr_pdsm_health,
+       },
+       /* Empty */
+       [PAPR_PDSM_MAX] = {
+               .size_in = 0,
+               .size_out = 0,
+               .service = NULL,
+       },
+};
+
+/* Given a valid pdsm cmd return its command descriptor else return NULL */
+static inline const struct pdsm_cmd_desc *pdsm_cmd_desc(enum papr_pdsm cmd)
+{
+       if (cmd >= 0 || cmd < ARRAY_SIZE(__pdsm_cmd_descriptors))
+               return &__pdsm_cmd_descriptors[cmd];
+
+       return NULL;
+}
+
+/*
+ * For a given pdsm request call an appropriate service function.
+ * Returns errors if any while handling the pdsm command package.
+ */
+static int papr_scm_service_pdsm(struct papr_scm_priv *p,
+                                struct nd_cmd_pkg *pkg)
+{
+       /* Get the PDSM header and PDSM command */
+       struct nd_pkg_pdsm *pdsm_pkg = (struct nd_pkg_pdsm *)pkg->nd_payload;
+       enum papr_pdsm pdsm = (enum papr_pdsm)pkg->nd_command;
+       const struct pdsm_cmd_desc *pdsc;
+       int rc;
+
+       /* Fetch corresponding pdsm descriptor for validation and servicing */
+       pdsc = pdsm_cmd_desc(pdsm);
+
+       /* Validate pdsm descriptor */
+       /* Ensure that reserved fields are 0 */
+       if (pdsm_pkg->reserved[0] || pdsm_pkg->reserved[1]) {
+               dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Invalid reserved field\n",
+                       pdsm);
+               return -EINVAL;
+       }
+
+       /* If pdsm expects some input, then ensure that the size_in matches */
+       if (pdsc->size_in &&
+           pkg->nd_size_in != (pdsc->size_in + ND_PDSM_HDR_SIZE)) {
+               dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Mismatched size_in=%d\n",
+                       pdsm, pkg->nd_size_in);
+               return -EINVAL;
+       }
+
+       /* If pdsm wants to return data, then ensure that  size_out matches */
+       if (pdsc->size_out &&
+           pkg->nd_size_out != (pdsc->size_out + ND_PDSM_HDR_SIZE)) {
+               dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Mismatched size_out=%d\n",
+                       pdsm, pkg->nd_size_out);
+               return -EINVAL;
+       }
+
+       /* Service the pdsm */
+       if (pdsc->service) {
+               dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Servicing..\n", pdsm);
+
+               rc = pdsc->service(p, &pdsm_pkg->payload);
+
+               if (rc < 0) {
+                       /* error encountered while servicing pdsm */
+                       pdsm_pkg->cmd_status = rc;
+                       pkg->nd_fw_size = ND_PDSM_HDR_SIZE;
+               } else {
+                       /* pdsm serviced and 'rc' bytes written to payload */
+                       pdsm_pkg->cmd_status = 0;
+                       pkg->nd_fw_size = ND_PDSM_HDR_SIZE + rc;
+               }
+       } else {
+               dev_dbg(&p->pdev->dev, "PDSM[0x%x]: Unsupported PDSM request\n",
+                       pdsm);
+               pdsm_pkg->cmd_status = -ENOENT;
+               pkg->nd_fw_size = ND_PDSM_HDR_SIZE;
+       }
+
+       return pdsm_pkg->cmd_status;
+}
+
 static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
                          struct nvdimm *nvdimm, unsigned int cmd, void *buf,
                          unsigned int buf_len, int *cmd_rc)
 {
        struct nd_cmd_get_config_size *get_size_hdr;
+       struct nd_cmd_pkg *call_pkg = NULL;
        struct papr_scm_priv *p;
+       int rc;
 
-       /* Only dimm-specific calls are supported atm */
-       if (!nvdimm)
-               return -EINVAL;
+       rc = is_cmd_valid(nvdimm, cmd, buf, buf_len);
+       if (rc) {
+               pr_debug("Invalid cmd=0x%x. Err=%d\n", cmd, rc);
+               return rc;
+       }
+
+       /* Use a local variable in case cmd_rc pointer is NULL */
+       if (!cmd_rc)
+               cmd_rc = &rc;
 
        p = nvdimm_provider_data(nvdimm);
 
@@ -277,7 +616,13 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
                *cmd_rc = papr_scm_meta_set(p, buf);
                break;
 
+       case ND_CMD_CALL:
+               call_pkg = (struct nd_cmd_pkg *)buf;
+               *cmd_rc = papr_scm_service_pdsm(p, call_pkg);
+               break;
+
        default:
+               dev_dbg(&p->pdev->dev, "Unknown command = %d\n", cmd);
                return -EINVAL;
        }
 
@@ -286,6 +631,64 @@ static int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc,
        return 0;
 }
 
+static ssize_t flags_show(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       struct nvdimm *dimm = to_nvdimm(dev);
+       struct papr_scm_priv *p = nvdimm_provider_data(dimm);
+       struct seq_buf s;
+       u64 health;
+       int rc;
+
+       rc = drc_pmem_query_health(p);
+       if (rc)
+               return rc;
+
+       /* Copy health_bitmap locally, check masks & update out buffer */
+       health = READ_ONCE(p->health_bitmap);
+
+       seq_buf_init(&s, buf, PAGE_SIZE);
+       if (health & PAPR_PMEM_UNARMED_MASK)
+               seq_buf_printf(&s, "not_armed ");
+
+       if (health & PAPR_PMEM_BAD_SHUTDOWN_MASK)
+               seq_buf_printf(&s, "flush_fail ");
+
+       if (health & PAPR_PMEM_BAD_RESTORE_MASK)
+               seq_buf_printf(&s, "restore_fail ");
+
+       if (health & PAPR_PMEM_ENCRYPTED)
+               seq_buf_printf(&s, "encrypted ");
+
+       if (health & PAPR_PMEM_SMART_EVENT_MASK)
+               seq_buf_printf(&s, "smart_notify ");
+
+       if (health & PAPR_PMEM_SCRUBBED_AND_LOCKED)
+               seq_buf_printf(&s, "scrubbed locked ");
+
+       if (seq_buf_used(&s))
+               seq_buf_printf(&s, "\n");
+
+       return seq_buf_used(&s);
+}
+DEVICE_ATTR_RO(flags);
+
+/* papr_scm specific dimm attributes */
+static struct attribute *papr_nd_attributes[] = {
+       &dev_attr_flags.attr,
+       NULL,
+};
+
+static struct attribute_group papr_nd_attribute_group = {
+       .name = "papr",
+       .attrs = papr_nd_attributes,
+};
+
+static const struct attribute_group *papr_nd_attr_groups[] = {
+       &papr_nd_attribute_group,
+       NULL,
+};
+
 static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
 {
        struct device *dev = &p->pdev->dev;
@@ -312,8 +715,8 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
        dimm_flags = 0;
        set_bit(NDD_LABELING, &dimm_flags);
 
-       p->nvdimm = nvdimm_create(p->bus, p, NULL, dimm_flags,
-                                 PAPR_SCM_DIMM_CMD_MASK, 0, NULL);
+       p->nvdimm = nvdimm_create(p->bus, p, papr_nd_attr_groups,
+                                 dimm_flags, PAPR_SCM_DIMM_CMD_MASK, 0, NULL);
        if (!p->nvdimm) {
                dev_err(dev, "Error creating DIMM object for %pOF\n", p->dn);
                goto err;
@@ -399,6 +802,9 @@ static int papr_scm_probe(struct platform_device *pdev)
        if (!p)
                return -ENOMEM;
 
+       /* Initialize the dimm mutex */
+       mutex_init(&p->health_mutex);
+
        /* optional DT properties */
        of_property_read_u32(dn, "ibm,metadata-size", &metadata_size);
 
index 4a8874b..040b9d0 100644 (file)
@@ -1066,10 +1066,10 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
 
        if (is_in_pci_mem_space(addr)) {
                if (user_mode(regs))
-                       ret = probe_user_read(&inst, (void __user *)regs->nip,
-                                             sizeof(inst));
+                       ret = copy_from_user_nofault(&inst,
+                                       (void __user *)regs->nip, sizeof(inst));
                else
-                       ret = probe_kernel_address((void *)regs->nip, inst);
+                       ret = get_kernel_nofault(inst, (void *)regs->nip);
 
                if (!ret && mcheck_handle_load(regs, inst)) {
                        regs->nip += 4;
index d969bab..262e5bb 100644 (file)
                        "       bnez %1, 0b\n"                          \
                        "1:\n"                                          \
                        : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr)    \
-                       : "rJ" (__old), "rJ" (__new)                    \
+                       : "rJ" ((long)__old), "rJ" (__new)              \
                        : "memory");                                    \
                break;                                                  \
        case 8:                                                         \
                        RISCV_ACQUIRE_BARRIER                           \
                        "1:\n"                                          \
                        : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr)    \
-                       : "rJ" (__old), "rJ" (__new)                    \
+                       : "rJ" ((long)__old), "rJ" (__new)              \
                        : "memory");                                    \
                break;                                                  \
        case 8:                                                         \
                        "       bnez %1, 0b\n"                          \
                        "1:\n"                                          \
                        : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr)    \
-                       : "rJ" (__old), "rJ" (__new)                    \
+                       : "rJ" ((long)__old), "rJ" (__new)              \
                        : "memory");                                    \
                break;                                                  \
        case 8:                                                         \
                        "       fence rw, rw\n"                         \
                        "1:\n"                                          \
                        : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr)    \
-                       : "rJ" (__old), "rJ" (__new)                    \
+                       : "rJ" ((long)__old), "rJ" (__new)              \
                        : "memory");                                    \
                break;                                                  \
        case 8:                                                         \
index 0839661..2ff63d0 100644 (file)
@@ -38,7 +38,8 @@ static int ftrace_check_current_call(unsigned long hook_pos,
         * Read the text we want to modify;
         * return must be -EFAULT on read error
         */
-       if (probe_kernel_read(replaced, (void *)hook_pos, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(replaced, (void *)hook_pos,
+                       MCOUNT_INSN_SIZE))
                return -EFAULT;
 
        /*
index f16ade8..c3275f4 100644 (file)
@@ -62,7 +62,7 @@ int get_step_address(struct pt_regs *regs, unsigned long *next_addr)
        unsigned int rs1_num, rs2_num;
        int op_code;
 
-       if (probe_kernel_address((void *)pc, op_code))
+       if (get_kernel_nofault(op_code, (void *)pc))
                return -EINVAL;
        if ((op_code & __INSN_LENGTH_MASK) != __INSN_LENGTH_GE_32) {
                if (is_c_jalr_insn(op_code) || is_c_jr_insn(op_code)) {
@@ -146,14 +146,14 @@ int do_single_step(struct pt_regs *regs)
                return error;
 
        /* Store the op code in the stepped address */
-       error = probe_kernel_address((void *)addr, stepped_opcode);
+       error = get_kernel_nofault(stepped_opcode, (void *)addr);
        if (error)
                return error;
 
        stepped_address = addr;
 
        /* Replace the op code with the break instruction */
-       error = probe_kernel_write((void *)stepped_address,
+       error = copy_to_kernel_nofault((void *)stepped_address,
                                   arch_kgdb_ops.gdb_bpt_instr,
                                   BREAK_INSTR_SIZE);
        /* Flush and return */
@@ -173,7 +173,7 @@ int do_single_step(struct pt_regs *regs)
 static void undo_single_step(struct pt_regs *regs)
 {
        if (stepped_opcode != 0) {
-               probe_kernel_write((void *)stepped_address,
+               copy_to_kernel_nofault((void *)stepped_address,
                                   (void *)&stepped_opcode, BREAK_INSTR_SIZE);
                flush_icache_range(stepped_address,
                                   stepped_address + BREAK_INSTR_SIZE);
index d4a64df..3fe7a52 100644 (file)
@@ -63,7 +63,7 @@ static int patch_insn_write(void *addr, const void *insn, size_t len)
 
        waddr = patch_map(addr, FIX_TEXT_POKE0);
 
-       ret = probe_kernel_write(waddr, insn, len);
+       ret = copy_to_kernel_nofault(waddr, insn, len);
 
        patch_unmap(FIX_TEXT_POKE0);
 
@@ -76,7 +76,7 @@ NOKPROBE_SYMBOL(patch_insn_write);
 #else
 static int patch_insn_write(void *addr, const void *insn, size_t len)
 {
-       return probe_kernel_write(addr, insn, len);
+       return copy_to_kernel_nofault(addr, insn, len);
 }
 NOKPROBE_SYMBOL(patch_insn_write);
 #endif /* CONFIG_MMU */
index f3619f5..12f8a7f 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/syscalls.h>
 #include <asm/unistd.h>
 #include <asm/cacheflush.h>
+#include <asm-generic/mman-common.h>
 
 static long riscv_sys_mmap(unsigned long addr, unsigned long len,
                           unsigned long prot, unsigned long flags,
@@ -16,6 +17,11 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
 {
        if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
                return -EINVAL;
+
+       if ((prot & PROT_WRITE) && (prot & PROT_EXEC))
+               if (unlikely(!(prot & PROT_READ)))
+                       return -EINVAL;
+
        return ksys_mmap_pgoff(addr, len, prot, flags, fd,
                               offset >> (PAGE_SHIFT - page_shift_offset));
 }
index ecec177..7d95cce 100644 (file)
@@ -137,7 +137,7 @@ static inline unsigned long get_break_insn_length(unsigned long pc)
 {
        bug_insn_t insn;
 
-       if (probe_kernel_address((bug_insn_t *)pc, insn))
+       if (get_kernel_nofault(insn, (bug_insn_t *)pc))
                return 0;
 
        return GET_INSN_LENGTH(insn);
@@ -165,7 +165,7 @@ int is_valid_bugaddr(unsigned long pc)
 
        if (pc < VMALLOC_START)
                return 0;
-       if (probe_kernel_address((bug_insn_t *)pc, insn))
+       if (get_kernel_nofault(insn, (bug_insn_t *)pc))
                return 0;
        if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32)
                return (insn == __BUG_INSN_32);
index ec2c70f..289a9a5 100644 (file)
@@ -151,6 +151,7 @@ int set_memory_nx(unsigned long addr, int numpages)
 
 int set_direct_map_invalid_noflush(struct page *page)
 {
+       int ret;
        unsigned long start = (unsigned long)page_address(page);
        unsigned long end = start + PAGE_SIZE;
        struct pageattr_masks masks = {
@@ -158,11 +159,16 @@ int set_direct_map_invalid_noflush(struct page *page)
                .clear_mask = __pgprot(_PAGE_PRESENT)
        };
 
-       return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+       mmap_read_lock(&init_mm);
+       ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+       mmap_read_unlock(&init_mm);
+
+       return ret;
 }
 
 int set_direct_map_default_noflush(struct page *page)
 {
+       int ret;
        unsigned long start = (unsigned long)page_address(page);
        unsigned long end = start + PAGE_SIZE;
        struct pageattr_masks masks = {
@@ -170,7 +176,11 @@ int set_direct_map_default_noflush(struct page *page)
                .clear_mask = __pgprot(0)
        };
 
-       return walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+       mmap_read_lock(&init_mm);
+       ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+       mmap_read_unlock(&init_mm);
+
+       return ret;
 }
 
 void __kernel_map_pages(struct page *page, int numpages, int enable)
index 1948249..c7d7ede 100644 (file)
@@ -462,6 +462,7 @@ config NUMA
 
 config NODES_SHIFT
        int
+       depends on NEED_MULTIPLE_NODES
        default "1"
 
 config SCHED_SMT
index d977643..e1ae239 100644 (file)
@@ -693,7 +693,7 @@ static ssize_t prng_chunksize_show(struct device *dev,
                                   struct device_attribute *attr,
                                   char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size);
+       return scnprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size);
 }
 static DEVICE_ATTR(chunksize, 0444, prng_chunksize_show, NULL);
 
@@ -712,7 +712,7 @@ static ssize_t prng_counter_show(struct device *dev,
                counter = prng_data->prngws.byte_counter;
        mutex_unlock(&prng_data->mutex);
 
-       return snprintf(buf, PAGE_SIZE, "%llu\n", counter);
+       return scnprintf(buf, PAGE_SIZE, "%llu\n", counter);
 }
 static DEVICE_ATTR(byte_counter, 0444, prng_counter_show, NULL);
 
@@ -721,7 +721,7 @@ static ssize_t prng_errorflag_show(struct device *dev,
                                   struct device_attribute *attr,
                                   char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag);
+       return scnprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag);
 }
 static DEVICE_ATTR(errorflag, 0444, prng_errorflag_show, NULL);
 
@@ -731,9 +731,9 @@ static ssize_t prng_mode_show(struct device *dev,
                              char *buf)
 {
        if (prng_mode == PRNG_MODE_TDES)
-               return snprintf(buf, PAGE_SIZE, "TDES\n");
+               return scnprintf(buf, PAGE_SIZE, "TDES\n");
        else
-               return snprintf(buf, PAGE_SIZE, "SHA512\n");
+               return scnprintf(buf, PAGE_SIZE, "SHA512\n");
 }
 static DEVICE_ATTR(mode, 0444, prng_mode_show, NULL);
 
@@ -756,7 +756,7 @@ static ssize_t prng_reseed_limit_show(struct device *dev,
                                      struct device_attribute *attr,
                                      char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit);
+       return scnprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit);
 }
 static ssize_t prng_reseed_limit_store(struct device *dev,
                                       struct device_attribute *attr,
@@ -787,7 +787,7 @@ static ssize_t prng_strength_show(struct device *dev,
                                  struct device_attribute *attr,
                                  char *buf)
 {
-       return snprintf(buf, PAGE_SIZE, "256\n");
+       return scnprintf(buf, PAGE_SIZE, "256\n");
 }
 static DEVICE_ATTR(strength, 0444, prng_strength_show, NULL);
 
index f073292..d9d5de0 100644 (file)
@@ -33,7 +33,17 @@ static inline void syscall_rollback(struct task_struct *task,
 static inline long syscall_get_error(struct task_struct *task,
                                     struct pt_regs *regs)
 {
-       return IS_ERR_VALUE(regs->gprs[2]) ? regs->gprs[2] : 0;
+       unsigned long error = regs->gprs[2];
+#ifdef CONFIG_COMPAT
+       if (test_tsk_thread_flag(task, TIF_31BIT)) {
+               /*
+                * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+                * and will match correctly in comparisons.
+                */
+               error = (long)(int)error;
+       }
+#endif
+       return IS_ERR_VALUE(error) ? error : 0;
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
index 3bcfdeb..0cd085c 100644 (file)
@@ -36,6 +36,7 @@ struct vdso_data {
        __u32 tk_shift;                 /* Shift used for xtime_nsec    0x60 */
        __u32 ts_dir;                   /* TOD steering direction       0x64 */
        __u64 ts_end;                   /* TOD steering end             0x68 */
+       __u32 hrtimer_res;              /* hrtimer resolution           0x70 */
 };
 
 struct vdso_per_cpu_data {
index 165031b..5d8cc18 100644 (file)
@@ -76,6 +76,7 @@ int main(void)
        OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
        OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir);
        OFFSET(__VDSO_TS_END, vdso_data, ts_end);
+       OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res);
        OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
        OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
        OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val);
@@ -86,7 +87,6 @@ int main(void)
        DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
        DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
        DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
-       DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
        DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
        BLANK();
        /* idle data offsets */
index 50ff6dd..496f74d 100644 (file)
@@ -401,9 +401,9 @@ ENTRY(system_call)
        jnz     .Lsysc_nr_ok
        # svc 0: system call number in %r1
        llgfr   %r1,%r1                         # clear high word in r1
+       sth     %r1,__PT_INT_CODE+2(%r11)
        cghi    %r1,NR_syscalls
        jnl     .Lsysc_nr_ok
-       sth     %r1,__PT_INT_CODE+2(%r11)
        slag    %r8,%r1,3
 .Lsysc_nr_ok:
        xc      __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
index 44e01dd..b388e87 100644 (file)
@@ -83,7 +83,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
 {
        struct ftrace_insn orig, new, old;
 
-       if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
+       if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old)))
                return -EFAULT;
        if (addr == MCOUNT_ADDR) {
                /* Initial code replacement */
@@ -105,7 +105,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
        struct ftrace_insn orig, new, old;
 
-       if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
+       if (copy_from_kernel_nofault(&old, (void *) rec->ip, sizeof(old)))
                return -EFAULT;
        /* Replace nop with an ftrace call. */
        ftrace_generate_nop_insn(&orig);
index ccea9a2..90a2a17 100644 (file)
@@ -181,7 +181,7 @@ static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
                struct kobj_attribute *attr,                            \
                char *page)                                             \
 {                                                                      \
-       return snprintf(page, PAGE_SIZE, _format, ##args);              \
+       return scnprintf(page, PAGE_SIZE, _format, ##args);             \
 }
 
 #define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk)                        \
index ce60a45..3cc15c0 100644 (file)
@@ -323,6 +323,25 @@ static inline void __poke_user_per(struct task_struct *child,
                child->thread.per_user.end = data;
 }
 
+static void fixup_int_code(struct task_struct *child, addr_t data)
+{
+       struct pt_regs *regs = task_pt_regs(child);
+       int ilc = regs->int_code >> 16;
+       u16 insn;
+
+       if (ilc > 6)
+               return;
+
+       if (ptrace_access_vm(child, regs->psw.addr - (regs->int_code >> 16),
+                       &insn, sizeof(insn), FOLL_FORCE) != sizeof(insn))
+               return;
+
+       /* double check that tracee stopped on svc instruction */
+       if ((insn >> 8) != 0xa)
+               return;
+
+       regs->int_code = 0x20000 | (data & 0xffff);
+}
 /*
  * Write a word to the user area of a process at location addr. This
  * operation does have an additional problem compared to peek_user.
@@ -334,7 +353,9 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
        struct user *dummy = NULL;
        addr_t offset;
 
+
        if (addr < (addr_t) &dummy->regs.acrs) {
+               struct pt_regs *regs = task_pt_regs(child);
                /*
                 * psw and gprs are stored on the stack
                 */
@@ -352,7 +373,11 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                                /* Invalid addressing mode bits */
                                return -EINVAL;
                }
-               *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
+
+               if (test_pt_regs_flag(regs, PIF_SYSCALL) &&
+                       addr == offsetof(struct user, regs.gprs[2]))
+                       fixup_int_code(child, data);
+               *(addr_t *)((addr_t) &regs->psw + addr) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
                /*
@@ -718,6 +743,10 @@ static int __poke_user_compat(struct task_struct *child,
                        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
                                (__u64)(tmp & PSW32_ADDR_AMODE);
                } else {
+
+                       if (test_pt_regs_flag(regs, PIF_SYSCALL) &&
+                               addr == offsetof(struct compat_user, regs.gprs[2]))
+                               fixup_int_code(child, data);
                        /* gpr 0-15 */
                        *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
                }
@@ -837,40 +866,66 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
        unsigned long mask = -1UL;
+       long ret = -1;
+
+       if (is_compat_task())
+               mask = 0xffffffff;
 
        /*
         * The sysc_tracesys code in entry.S stored the system
         * call number to gprs[2].
         */
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
-           (tracehook_report_syscall_entry(regs) ||
-            regs->gprs[2] >= NR_syscalls)) {
+           tracehook_report_syscall_entry(regs)) {
                /*
-                * Tracing decided this syscall should not happen or the
-                * debugger stored an invalid system call number. Skip
+                * Tracing decided this syscall should not happen. Skip
                 * the system call and the system call restart handling.
                 */
-               clear_pt_regs_flag(regs, PIF_SYSCALL);
-               return -1;
+               goto skip;
        }
 
+#ifdef CONFIG_SECCOMP
        /* Do the secure computing check after ptrace. */
-       if (secure_computing()) {
-               /* seccomp failures shouldn't expose any additional code. */
-               return -1;
+       if (unlikely(test_thread_flag(TIF_SECCOMP))) {
+               struct seccomp_data sd;
+
+               if (is_compat_task()) {
+                       sd.instruction_pointer = regs->psw.addr & 0x7fffffff;
+                       sd.arch = AUDIT_ARCH_S390;
+               } else {
+                       sd.instruction_pointer = regs->psw.addr;
+                       sd.arch = AUDIT_ARCH_S390X;
+               }
+
+               sd.nr = regs->int_code & 0xffff;
+               sd.args[0] = regs->orig_gpr2 & mask;
+               sd.args[1] = regs->gprs[3] & mask;
+               sd.args[2] = regs->gprs[4] & mask;
+               sd.args[3] = regs->gprs[5] & mask;
+               sd.args[4] = regs->gprs[6] & mask;
+               sd.args[5] = regs->gprs[7] & mask;
+
+               if (__secure_computing(&sd) == -1)
+                       goto skip;
        }
+#endif /* CONFIG_SECCOMP */
 
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
-               trace_sys_enter(regs, regs->gprs[2]);
+               trace_sys_enter(regs, regs->int_code & 0xffff);
 
-       if (is_compat_task())
-               mask = 0xffffffff;
 
-       audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask,
+       audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask,
                            regs->gprs[3] &mask, regs->gprs[4] &mask,
                            regs->gprs[5] &mask);
 
+       if ((signed long)regs->gprs[2] >= NR_syscalls) {
+               regs->gprs[2] = -ENOSYS;
+               ret = -ENOSYS;
+       }
        return regs->gprs[2];
+skip:
+       clear_pt_regs_flag(regs, PIF_SYSCALL);
+       return ret;
 }
 
 asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
index f9d070d..b1113b5 100644 (file)
@@ -301,6 +301,7 @@ void update_vsyscall(struct timekeeper *tk)
 
        vdso_data->tk_mult = tk->tkr_mono.mult;
        vdso_data->tk_shift = tk->tkr_mono.shift;
+       vdso_data->hrtimer_res = hrtimer_resolution;
        smp_wmb();
        ++vdso_data->tb_update_count;
 }
index 66e89b2..c296e5c 100644 (file)
@@ -331,7 +331,7 @@ EXPORT_SYMBOL_GPL(arch_make_page_accessible);
 static ssize_t uv_query_facilities(struct kobject *kobj,
                                   struct kobj_attribute *attr, char *page)
 {
-       return snprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n",
+       return scnprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n",
                        uv_info.inst_calls_list[0],
                        uv_info.inst_calls_list[1],
                        uv_info.inst_calls_list[2],
@@ -344,7 +344,7 @@ static struct kobj_attribute uv_query_facilities_attr =
 static ssize_t uv_query_max_guest_cpus(struct kobject *kobj,
                                       struct kobj_attribute *attr, char *page)
 {
-       return snprintf(page, PAGE_SIZE, "%d\n",
+       return scnprintf(page, PAGE_SIZE, "%d\n",
                        uv_info.max_guest_cpus);
 }
 
@@ -354,7 +354,7 @@ static struct kobj_attribute uv_query_max_guest_cpus_attr =
 static ssize_t uv_query_max_guest_vms(struct kobject *kobj,
                                      struct kobj_attribute *attr, char *page)
 {
-       return snprintf(page, PAGE_SIZE, "%d\n",
+       return scnprintf(page, PAGE_SIZE, "%d\n",
                        uv_info.max_num_sec_conf);
 }
 
@@ -364,7 +364,7 @@ static struct kobj_attribute uv_query_max_guest_vms_attr =
 static ssize_t uv_query_max_guest_addr(struct kobject *kobj,
                                       struct kobj_attribute *attr, char *page)
 {
-       return snprintf(page, PAGE_SIZE, "%lx\n",
+       return scnprintf(page, PAGE_SIZE, "%lx\n",
                        uv_info.max_sec_stor_addr);
 }
 
index bec19e7..4a66a1c 100644 (file)
@@ -18,8 +18,8 @@ KBUILD_AFLAGS_64 += -m64 -s
 
 KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
 KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin
-KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
-                   -Wl,--hash-style=both
+ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \
+            --hash-style=both --build-id -T
 
 $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
 $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64)
@@ -37,8 +37,8 @@ KASAN_SANITIZE := n
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE
-       $(call if_changed,vdso64ld)
+$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE
+       $(call if_changed,ld)
 
 # strip rule for the .so file
 $(obj)/%.so: OBJCOPYFLAGS := -S
@@ -50,8 +50,6 @@ $(obj-vdso64): %.o: %.S FORCE
        $(call if_changed_dep,vdso64as)
 
 # actual build commands
-quiet_cmd_vdso64ld = VDSO64L $@
-      cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
 quiet_cmd_vdso64as = VDSO64A $@
       cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
 
index 0814353..0c79caa 100644 (file)
        .type  __kernel_clock_getres,@function
 __kernel_clock_getres:
        CFI_STARTPROC
-       larl    %r1,4f
+       larl    %r1,3f
+       lg      %r0,0(%r1)
        cghi    %r2,__CLOCK_REALTIME_COARSE
        je      0f
        cghi    %r2,__CLOCK_MONOTONIC_COARSE
        je      0f
-       larl    %r1,3f
+       larl    %r1,_vdso_data
+       llgf    %r0,__VDSO_CLOCK_REALTIME_RES(%r1)
        cghi    %r2,__CLOCK_REALTIME
        je      0f
        cghi    %r2,__CLOCK_MONOTONIC
@@ -36,7 +38,6 @@ __kernel_clock_getres:
        jz      2f
 0:     ltgr    %r3,%r3
        jz      1f                              /* res == NULL */
-       lg      %r0,0(%r1)
        xc      0(8,%r3),0(%r3)                 /* set tp->tv_sec to zero */
        stg     %r0,8(%r3)                      /* store tp->tv_usec */
 1:     lghi    %r2,0
@@ -45,6 +46,5 @@ __kernel_clock_getres:
        svc     0
        br      %r14
        CFI_ENDPROC
-3:     .quad   __CLOCK_REALTIME_RES
-4:     .quad   __CLOCK_COARSE_RES
+3:     .quad   __CLOCK_COARSE_RES
        .size   __kernel_clock_getres,.-__kernel_clock_getres
index 6a24751..d53c2e2 100644 (file)
@@ -105,7 +105,7 @@ static int bad_address(void *p)
 {
        unsigned long dummy;
 
-       return probe_kernel_address((unsigned long *)p, dummy);
+       return get_kernel_nofault(dummy, (unsigned long *)p);
 }
 
 static void dump_pagetable(unsigned long asce, unsigned long address)
index 1b04270..0646c59 100644 (file)
@@ -119,7 +119,7 @@ static void ftrace_mod_code(void)
         * But if one were to fail, then they all should, and if one were
         * to succeed, then they all should.
         */
-       mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
+       mod_code_status = copy_to_kernel_nofault(mod_code_ip, mod_code_newcode,
                                             MCOUNT_INSN_SIZE);
 
        /* if we fail, then kill any new writers */
@@ -203,7 +203,7 @@ static int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
         */
 
        /* read the text we want to modify */
-       if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(replaced, (void *)ip, MCOUNT_INSN_SIZE))
                return -EFAULT;
 
        /* Make sure it is what we expect it to be */
@@ -268,7 +268,7 @@ static int ftrace_mod(unsigned long ip, unsigned long old_addr,
 {
        unsigned char code[MCOUNT_INSN_SIZE];
 
-       if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
+       if (copy_from_kernel_nofault(code, (void *)ip, MCOUNT_INSN_SIZE))
                return -EFAULT;
 
        if (old_addr != __raw_readl((unsigned long *)code))
index a330254..9c3d32b 100644 (file)
@@ -118,7 +118,7 @@ int is_valid_bugaddr(unsigned long addr)
 
        if (addr < PAGE_OFFSET)
                return 0;
-       if (probe_kernel_address((insn_size_t *)addr, opcode))
+       if (get_kernel_nofault(opcode, (insn_size_t *)addr))
                return 0;
        if (opcode == TRAPA_BUG_OPCODE)
                return 1;
index e929c09..8ccd568 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/kernel.h>
 #include <os.h>
 
-bool probe_kernel_read_allowed(const void *src, size_t size)
+bool copy_from_kernel_nofault_allowed(const void *src, size_t size)
 {
        void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE);
 
index ebedeab..255b2dd 100644 (file)
@@ -278,7 +278,7 @@ static inline unsigned long *regs_get_kernel_stack_nth_addr(struct pt_regs *regs
 }
 
 /* To avoid include hell, we can't include uaccess.h */
-extern long probe_kernel_read(void *dst, const void *src, size_t size);
+extern long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
 
 /**
  * regs_get_kernel_stack_nth() - get Nth entry of the stack
@@ -298,7 +298,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
 
        addr = regs_get_kernel_stack_nth_addr(regs, n);
        if (addr) {
-               ret = probe_kernel_read(&val, addr, sizeof(val));
+               ret = copy_from_kernel_nofault(&val, addr, sizeof(val));
                if (!ret)
                        return val;
        }
index 456511b..b037cfa 100644 (file)
@@ -106,7 +106,7 @@ void show_opcodes(struct pt_regs *regs, const char *loglvl)
        bad_ip = user_mode(regs) &&
                __chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
 
-       if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue,
+       if (bad_ip || copy_from_kernel_nofault(opcodes, (u8 *)prologue,
                                        OPCODE_BUFSIZE)) {
                printk("%sCode: Bad RIP value.\n", loglvl);
        } else {
index c84d28e..5150456 100644 (file)
@@ -86,7 +86,7 @@ static int ftrace_verify_code(unsigned long ip, const char *old_code)
         * sure what we read is what we expected it to be before modifying it.
         */
        /* read the text we want to modify */
-       if (probe_kernel_read(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) {
+       if (copy_from_kernel_nofault(cur_code, (void *)ip, MCOUNT_INSN_SIZE)) {
                WARN_ON(1);
                return -EFAULT;
        }
@@ -355,7 +355,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
        npages = DIV_ROUND_UP(*tramp_size, PAGE_SIZE);
 
        /* Copy ftrace_caller onto the trampoline memory */
-       ret = probe_kernel_read(trampoline, (void *)start_offset, size);
+       ret = copy_from_kernel_nofault(trampoline, (void *)start_offset, size);
        if (WARN_ON(ret < 0))
                goto fail;
 
@@ -363,13 +363,13 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)
 
        /* The trampoline ends with ret(q) */
        retq = (unsigned long)ftrace_stub;
-       ret = probe_kernel_read(ip, (void *)retq, RET_SIZE);
+       ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE);
        if (WARN_ON(ret < 0))
                goto fail;
 
        if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) {
                ip = trampoline + (ftrace_regs_caller_ret - ftrace_regs_caller);
-               ret = probe_kernel_read(ip, (void *)retq, RET_SIZE);
+               ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE);
                if (WARN_ON(ret < 0))
                        goto fail;
        }
@@ -506,7 +506,7 @@ static void *addr_from_call(void *ptr)
        union text_poke_insn call;
        int ret;
 
-       ret = probe_kernel_read(&call, ptr, CALL_INSN_SIZE);
+       ret = copy_from_kernel_nofault(&call, ptr, CALL_INSN_SIZE);
        if (WARN_ON_ONCE(ret < 0))
                return NULL;
 
index c44fe7d..68acd30 100644 (file)
@@ -732,11 +732,11 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
        int err;
 
        bpt->type = BP_BREAKPOINT;
-       err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
+       err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
                                BREAK_INSTR_SIZE);
        if (err)
                return err;
-       err = probe_kernel_write((char *)bpt->bpt_addr,
+       err = copy_to_kernel_nofault((char *)bpt->bpt_addr,
                                 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
        if (!err)
                return err;
@@ -768,7 +768,7 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
        return 0;
 
 knl_write:
-       return probe_kernel_write((char *)bpt->bpt_addr,
+       return copy_to_kernel_nofault((char *)bpt->bpt_addr,
                                  (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
 }
 
index 3bafe1b..ada39dd 100644 (file)
@@ -243,7 +243,7 @@ __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
         * Fortunately, we know that the original code is the ideal 5-byte
         * long NOP.
         */
-       if (probe_kernel_read(buf, (void *)addr,
+       if (copy_from_kernel_nofault(buf, (void *)addr,
                MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
                return 0UL;
 
@@ -346,7 +346,8 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
                return 0;
 
        /* This can access kernel text if given address is not recovered */
-       if (probe_kernel_read(dest, (void *)recovered_insn, MAX_INSN_SIZE))
+       if (copy_from_kernel_nofault(dest, (void *)recovered_insn,
+                       MAX_INSN_SIZE))
                return 0;
 
        kernel_insn_init(insn, dest, MAX_INSN_SIZE);
@@ -753,16 +754,11 @@ asm(
 NOKPROBE_SYMBOL(kretprobe_trampoline);
 STACK_FRAME_NON_STANDARD(kretprobe_trampoline);
 
-static struct kprobe kretprobe_kprobe = {
-       .addr = (void *)kretprobe_trampoline,
-};
-
 /*
  * Called from kretprobe_trampoline
  */
 __used __visible void *trampoline_handler(struct pt_regs *regs)
 {
-       struct kprobe_ctlblk *kcb;
        struct kretprobe_instance *ri = NULL;
        struct hlist_head *head, empty_rp;
        struct hlist_node *tmp;
@@ -772,16 +768,12 @@ __used __visible void *trampoline_handler(struct pt_regs *regs)
        void *frame_pointer;
        bool skipped = false;
 
-       preempt_disable();
-
        /*
         * Set a dummy kprobe for avoiding kretprobe recursion.
         * Since kretprobe never run in kprobe handler, kprobe must not
         * be running at this point.
         */
-       kcb = get_kprobe_ctlblk();
-       __this_cpu_write(current_kprobe, &kretprobe_kprobe);
-       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+       kprobe_busy_begin();
 
        INIT_HLIST_HEAD(&empty_rp);
        kretprobe_hash_lock(current, &head, &flags);
@@ -857,7 +849,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs)
                        __this_cpu_write(current_kprobe, &ri->rp->kp);
                        ri->ret_addr = correct_ret_addr;
                        ri->rp->handler(ri, regs);
-                       __this_cpu_write(current_kprobe, &kretprobe_kprobe);
+                       __this_cpu_write(current_kprobe, &kprobe_busy);
                }
 
                recycle_rp_inst(ri, &empty_rp);
@@ -873,8 +865,7 @@ __used __visible void *trampoline_handler(struct pt_regs *regs)
 
        kretprobe_hash_unlock(current, &flags);
 
-       __this_cpu_write(current_kprobe, NULL);
-       preempt_enable();
+       kprobe_busy_end();
 
        hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
                hlist_del(&ri->hlist);
index 321c199..7af4c61 100644 (file)
@@ -56,7 +56,7 @@ found:
         * overwritten by jump destination address. In this case, original
         * bytes must be recovered from op->optinsn.copied_insn buffer.
         */
-       if (probe_kernel_read(buf, (void *)addr,
+       if (copy_from_kernel_nofault(buf, (void *)addr,
                MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
                return 0UL;
 
index ee02863..9e1def3 100644 (file)
@@ -94,12 +94,12 @@ static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short
 }
 
 static bool probe_list(struct pci_dev *pdev, unsigned short vendor,
-                      const unsigned char *rom_list)
+                      const void *rom_list)
 {
        unsigned short device;
 
        do {
-               if (probe_kernel_address(rom_list, device) != 0)
+               if (get_kernel_nofault(device, rom_list) != 0)
                        device = 0;
 
                if (device && match_id(pdev, vendor, device))
@@ -119,19 +119,19 @@ static struct resource *find_oprom(struct pci_dev *pdev)
        for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
                struct resource *res = &adapter_rom_resources[i];
                unsigned short offset, vendor, device, list, rev;
-               const unsigned char *rom;
+               const void *rom;
 
                if (res->end == 0)
                        break;
 
                rom = isa_bus_to_virt(res->start);
-               if (probe_kernel_address(rom + 0x18, offset) != 0)
+               if (get_kernel_nofault(offset, rom + 0x18) != 0)
                        continue;
 
-               if (probe_kernel_address(rom + offset + 0x4, vendor) != 0)
+               if (get_kernel_nofault(vendor, rom + offset + 0x4) != 0)
                        continue;
 
-               if (probe_kernel_address(rom + offset + 0x6, device) != 0)
+               if (get_kernel_nofault(device, rom + offset + 0x6) != 0)
                        continue;
 
                if (match_id(pdev, vendor, device)) {
@@ -139,8 +139,8 @@ static struct resource *find_oprom(struct pci_dev *pdev)
                        break;
                }
 
-               if (probe_kernel_address(rom + offset + 0x8, list) == 0 &&
-                   probe_kernel_address(rom + offset + 0xc, rev) == 0 &&
+               if (get_kernel_nofault(list, rom + offset + 0x8) == 0 &&
+                   get_kernel_nofault(rev, rom + offset + 0xc) == 0 &&
                    rev >= 3 && list &&
                    probe_list(pdev, vendor, rom + offset + list)) {
                        oprom = res;
@@ -183,14 +183,14 @@ static int __init romsignature(const unsigned char *rom)
        const unsigned short * const ptr = (const unsigned short *)rom;
        unsigned short sig;
 
-       return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
+       return get_kernel_nofault(sig, ptr) == 0 && sig == ROMSIGNATURE;
 }
 
 static int __init romchecksum(const unsigned char *rom, unsigned long length)
 {
        unsigned char sum, c;
 
-       for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
+       for (sum = 0; length && get_kernel_nofault(c, rom++) == 0; length--)
                sum += c;
        return !length && !sum;
 }
@@ -211,7 +211,7 @@ void __init probe_roms(void)
 
                video_rom_resource.start = start;
 
-               if (probe_kernel_address(rom + 2, c) != 0)
+               if (get_kernel_nofault(c, rom + 2) != 0)
                        continue;
 
                /* 0 < length <= 0x7f * 512, historically */
@@ -249,7 +249,7 @@ void __init probe_roms(void)
                if (!romsignature(rom))
                        continue;
 
-               if (probe_kernel_address(rom + 2, c) != 0)
+               if (get_kernel_nofault(c, rom + 2) != 0)
                        continue;
 
                /* 0 < length <= 0x7f * 512, historically */
index af75109..f9727b9 100644 (file)
@@ -91,7 +91,7 @@ int is_valid_bugaddr(unsigned long addr)
        if (addr < TASK_SIZE_MAX)
                return 0;
 
-       if (probe_kernel_address((unsigned short *)addr, ud))
+       if (get_kernel_nofault(ud, (unsigned short *)addr))
                return 0;
 
        return ud == INSN_UD0 || ud == INSN_UD2;
@@ -488,7 +488,8 @@ static enum kernel_gp_hint get_kernel_gp_address(struct pt_regs *regs,
        u8 insn_buf[MAX_INSN_SIZE];
        struct insn insn;
 
-       if (probe_kernel_read(insn_buf, (void *)regs->ip, MAX_INSN_SIZE))
+       if (copy_from_kernel_nofault(insn_buf, (void *)regs->ip,
+                       MAX_INSN_SIZE))
                return GP_NO_HINT;
 
        kernel_insn_init(&insn, insn_buf, MAX_INSN_SIZE);
index 66be9bd..1ead568 100644 (file)
@@ -99,7 +99,7 @@ check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr,
                return !instr_lo || (instr_lo>>1) == 1;
        case 0x00:
                /* Prefetch instruction is 0x0F0D or 0x0F18 */
-               if (probe_kernel_address(instr, opcode))
+               if (get_kernel_nofault(opcode, instr))
                        return 0;
 
                *prefetch = (instr_lo == 0xF) &&
@@ -133,7 +133,7 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr)
        while (instr < max_instr) {
                unsigned char opcode;
 
-               if (probe_kernel_address(instr, opcode))
+               if (get_kernel_nofault(opcode, instr))
                        break;
 
                instr++;
@@ -301,7 +301,7 @@ static int bad_address(void *p)
 {
        unsigned long dummy;
 
-       return probe_kernel_address((unsigned long *)p, dummy);
+       return get_kernel_nofault(dummy, (unsigned long *)p);
 }
 
 static void dump_pagetable(unsigned long address)
@@ -442,7 +442,7 @@ static void show_ldttss(const struct desc_ptr *gdt, const char *name, u16 index)
                return;
        }
 
-       if (probe_kernel_read(&desc, (void *)(gdt->address + offset),
+       if (copy_from_kernel_nofault(&desc, (void *)(gdt->address + offset),
                              sizeof(struct ldttss_desc))) {
                pr_alert("%s: 0x%hx -- GDT entry is not readable\n",
                         name, index);
index bda909e..8b4afad 100644 (file)
@@ -737,7 +737,7 @@ static void __init test_wp_bit(void)
 
        __set_fixmap(FIX_WP_TEST, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO);
 
-       if (probe_kernel_write((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) {
+       if (copy_to_kernel_nofault((char *)fix_to_virt(FIX_WP_TEST), &z, 1)) {
                clear_fixmap(FIX_WP_TEST);
                printk(KERN_CONT "Ok.\n");
                return;
index e1d7d74..92ec176 100644 (file)
@@ -9,7 +9,7 @@ static __always_inline u64 canonical_address(u64 vaddr, u8 vaddr_bits)
        return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
 }
 
-bool probe_kernel_read_allowed(const void *unsafe_src, size_t size)
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
 {
        unsigned long vaddr = (unsigned long)unsafe_src;
 
@@ -22,7 +22,7 @@ bool probe_kernel_read_allowed(const void *unsafe_src, size_t size)
               canonical_address(vaddr, boot_cpu_data.x86_virt_bits) == vaddr;
 }
 #else
-bool probe_kernel_read_allowed(const void *unsafe_src, size_t size)
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
 {
        return (unsigned long)unsafe_src >= TASK_SIZE_MAX;
 }
index 9c97d81..4f15280 100644 (file)
@@ -302,7 +302,7 @@ static const struct pci_raw_ops *__init pci_find_bios(void)
             check <= (union bios32 *) __va(0xffff0);
             ++check) {
                long sig;
-               if (probe_kernel_address(&check->fields.signature, sig))
+               if (get_kernel_nofault(sig, &check->fields.signature))
                        continue;
 
                if (check->fields.signature != BIOS32_SIGNATURE)
index b8f7f19..30bd571 100644 (file)
@@ -287,8 +287,8 @@ void intel_scu_devices_create(void)
 
                adapter = i2c_get_adapter(i2c_bus[i]);
                if (adapter) {
-                       client = i2c_new_device(adapter, i2c_devs[i]);
-                       if (!client)
+                       client = i2c_new_client_device(adapter, i2c_devs[i]);
+                       if (IS_ERR(client))
                                pr_err("can't create i2c device %s\n",
                                        i2c_devs[i]->type);
                } else
index b04e6e7..088bd76 100644 (file)
@@ -34,6 +34,7 @@ KCOV_INSTRUMENT := n
 PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
 PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss
 PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
+PURGATORY_CFLAGS += $(call cc-option,-fno-stack-protector)
 
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
index 33b309d..acc49fa 100644 (file)
@@ -386,7 +386,7 @@ static void set_aliased_prot(void *v, pgprot_t prot)
 
        preempt_disable();
 
-       probe_kernel_read(&dummy, v, 1);
+       copy_from_kernel_nofault(&dummy, v, 1);
 
        if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
                BUG();
index 44f3d09..ae722f8 100644 (file)
@@ -376,7 +376,7 @@ static void __blk_mq_all_tag_iter(struct blk_mq_tags *tags,
 void blk_mq_all_tag_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn,
                void *priv)
 {
-       return __blk_mq_all_tag_iter(tags, fn, priv, BT_TAG_ITER_STATIC_RQS);
+       __blk_mq_all_tag_iter(tags, fn, priv, BT_TAG_ITER_STATIC_RQS);
 }
 
 /**
index 4f57d27..a9aa6d1 100644 (file)
@@ -3479,7 +3479,9 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
 
        if (set->nr_maps == 1 && nr_hw_queues > nr_cpu_ids)
                nr_hw_queues = nr_cpu_ids;
-       if (nr_hw_queues < 1 || nr_hw_queues == set->nr_hw_queues)
+       if (nr_hw_queues < 1)
+               return;
+       if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues)
                return;
 
        list_for_each_entry(q, &set->tag_list, tag_set_list)
index 6fdfcb4..d333786 100644 (file)
@@ -910,7 +910,7 @@ static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb)
                return false;
 
        disk = &vb->vblk.disk;
-       uuid_copy(&disk->disk_id, (uuid_t *)(buffer + 0x18 + r_name));
+       import_uuid(&disk->disk_id, buffer + 0x18 + r_name);
        return true;
 }
 
index 841580a..d8d6bea 100644 (file)
@@ -93,7 +93,7 @@ struct frag {                         /* VBLK Fragment handling */
        u8              num;            /* Total number of records */
        u8              rec;            /* This is record number n */
        u8              map;            /* Which portions are in use */
-       u8              data[0];
+       u8              data[];
 };
 
 /* In memory LDM database structures. */
index 535f1f8..5ebccbd 100644 (file)
@@ -178,8 +178,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
        if (IS_ERR(thread))
                goto err_put_larval;
 
-       wait_for_completion_interruptible(&larval->completion);
-
        return NOTIFY_STOP;
 
 err_put_larval:
index e2c8ab4..4c3bdff 100644 (file)
@@ -74,14 +74,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
                return PTR_ERR(areq);
 
        /* convert iovecs of output buffers into RX SGL */
-       err = af_alg_get_rsgl(sk, msg, flags, areq, -1, &len);
+       err = af_alg_get_rsgl(sk, msg, flags, areq, ctx->used, &len);
        if (err)
                goto free;
 
-       /* Process only as much RX buffers for which we have TX data */
-       if (len > ctx->used)
-               len = ctx->used;
-
        /*
         * If more buffers are to be expected to be processed, process only
         * full block size buffers.
index 37526eb..8d80d93 100644 (file)
@@ -1631,10 +1631,12 @@ static int drbg_uninstantiate(struct drbg_state *drbg)
        if (drbg->random_ready.func) {
                del_random_ready_callback(&drbg->random_ready);
                cancel_work_sync(&drbg->seed_work);
-               crypto_free_rng(drbg->jent);
-               drbg->jent = NULL;
        }
 
+       if (!IS_ERR_OR_NULL(drbg->jent))
+               crypto_free_rng(drbg->jent);
+       drbg->jent = NULL;
+
        if (drbg->d_ops)
                drbg->d_ops->crypto_fini(drbg);
        drbg_dealloc_state(drbg);
index 57d3b2e..0b2c20f 100644 (file)
@@ -120,7 +120,7 @@ static const u32 tegra_ahb_gizmo[] = {
 struct tegra_ahb {
        void __iomem    *regs;
        struct device   *dev;
-       u32             ctx[0];
+       u32             ctx[];
 };
 
 static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
index 69361ec..b1cd4d9 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/workqueue.h>
 #include <linux/scatterlist.h>
 #include <linux/io.h>
-#include <linux/async.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
 #include <linux/glob.h>
@@ -5778,7 +5777,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        /* perform each probe asynchronously */
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
-               async_schedule(async_port_probe, ap);
+               ap->cookie = async_schedule(async_port_probe, ap);
        }
 
        return 0;
@@ -5920,11 +5919,11 @@ void ata_host_detach(struct ata_host *host)
 {
        int i;
 
-       /* Ensure ata_port probe has completed */
-       async_synchronize_full();
-
-       for (i = 0; i < host->n_ports; i++)
+       for (i = 0; i < host->n_ports; i++) {
+               /* Ensure ata_port probe has completed */
+               async_synchronize_cookie(host->ports[i]->cookie + 1);
                ata_port_detach(host->ports[i]);
+       }
 
        /* the host is dead now, dissociate ACPI */
        ata_acpi_dissociate(host);
index 435781a..4633608 100644 (file)
@@ -3684,12 +3684,13 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *scmd = qc->scsicmd;
        const u8 *cdb = scmd->cmnd;
-       const u8 *p;
        u8 pg, spg;
        unsigned six_byte, pg_len, hdr_len, bd_len;
        int len;
        u16 fp = (u16)-1;
        u8 bp = 0xff;
+       u8 buffer[64];
+       const u8 *p = buffer;
 
        VPRINTK("ENTER\n");
 
@@ -3723,12 +3724,14 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
        if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len)
                goto invalid_param_len;
 
-       p = page_address(sg_page(scsi_sglist(scmd)));
-
        /* Move past header and block descriptors.  */
        if (len < hdr_len)
                goto invalid_param_len;
 
+       if (!sg_copy_to_buffer(scsi_sglist(scmd), scsi_sg_count(scmd),
+                              buffer, sizeof(buffer)))
+               goto invalid_param_len;
+
        if (six_byte)
                bd_len = p[3];
        else
index 980aacd..141ac60 100644 (file)
@@ -907,7 +907,7 @@ static int sata_rcar_probe(struct platform_device *pdev)
        pm_runtime_enable(dev);
        ret = pm_runtime_get_sync(dev);
        if (ret < 0)
-               goto err_pm_disable;
+               goto err_pm_put;
 
        host = ata_host_alloc(dev, 1);
        if (!host) {
@@ -937,7 +937,6 @@ static int sata_rcar_probe(struct platform_device *pdev)
 
 err_pm_put:
        pm_runtime_put(dev);
-err_pm_disable:
        pm_runtime_disable(dev);
        return ret;
 }
@@ -991,8 +990,10 @@ static int sata_rcar_resume(struct device *dev)
        int ret;
 
        ret = pm_runtime_get_sync(dev);
-       if (ret < 0)
+       if (ret < 0) {
+               pm_runtime_put(dev);
                return ret;
+       }
 
        if (priv->type == RCAR_GEN3_SATA) {
                sata_rcar_init_module(priv);
@@ -1017,8 +1018,10 @@ static int sata_rcar_restore(struct device *dev)
        int ret;
 
        ret = pm_runtime_get_sync(dev);
-       if (ret < 0)
+       if (ret < 0) {
+               pm_runtime_put(dev);
                return ret;
+       }
 
        sata_rcar_setup_port(host);
 
index 14345a8..33d0831 100644 (file)
@@ -620,7 +620,7 @@ struct fifo_buffer {
        unsigned int head_index;
        unsigned int size;
        int total; /* sum of all values */
-       int values[0];
+       int values[];
 };
 extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size);
 
index e6fc5ad..dea59c9 100644 (file)
@@ -271,7 +271,7 @@ struct p_rs_param {
        u32 resync_rate;
 
              /* Since protocol version 88 and higher. */
-       char verify_alg[0];
+       char verify_alg[];
 } __packed;
 
 struct p_rs_param_89 {
@@ -305,7 +305,7 @@ struct p_protocol {
        u32 two_primaries;
 
        /* Since protocol version 87 and higher. */
-       char integrity_alg[0];
+       char integrity_alg[];
 
 } __packed;
 
@@ -360,7 +360,7 @@ struct p_sizes {
        u16         dds_flags; /* use enum dds_flags here. */
 
        /* optional queue_limits if (agreed_features & DRBD_FF_WSAME) */
-       struct o_qlim qlim[0];
+       struct o_qlim qlim[];
 } __packed;
 
 struct p_state {
@@ -409,7 +409,7 @@ struct p_compressed_bm {
         */
        u8 encoding;
 
-       u8 code[0];
+       u8 code[];
 } __packed;
 
 struct p_delay_probe93 {
index c33bbbf..475e1a7 100644 (file)
@@ -1368,14 +1368,14 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
            lo->lo_sizelimit != info->lo_sizelimit) {
                size_changed = true;
                sync_blockdev(lo->lo_device);
-               kill_bdev(lo->lo_device);
+               invalidate_bdev(lo->lo_device);
        }
 
        /* I/O need to be drained during transfer transition */
        blk_mq_freeze_queue(lo->lo_queue);
 
        if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) {
-               /* If any pages were dirtied after kill_bdev(), try again */
+               /* If any pages were dirtied after invalidate_bdev(), try again */
                err = -EAGAIN;
                pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
                        __func__, lo->lo_number, lo->lo_file_name,
@@ -1615,11 +1615,11 @@ static int loop_set_block_size(struct loop_device *lo, unsigned long arg)
                return 0;
 
        sync_blockdev(lo->lo_device);
-       kill_bdev(lo->lo_device);
+       invalidate_bdev(lo->lo_device);
 
        blk_mq_freeze_queue(lo->lo_queue);
 
-       /* kill_bdev should have truncated all the pages */
+       /* invalidate_bdev should have truncated all the pages */
        if (lo->lo_device->bd_inode->i_mapping->nrpages) {
                err = -EAGAIN;
                pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n",
index 7420648..4f61e92 100644 (file)
@@ -1451,8 +1451,10 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req)
 static void rbd_osd_format_read(struct ceph_osd_request *osd_req)
 {
        struct rbd_obj_request *obj_request = osd_req->r_priv;
+       struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev;
+       struct ceph_options *opt = rbd_dev->rbd_client->client->options;
 
-       osd_req->r_flags = CEPH_OSD_FLAG_READ;
+       osd_req->r_flags = CEPH_OSD_FLAG_READ | opt->read_from_replica;
        osd_req->r_snapid = obj_request->img_request->snap_id;
 }
 
index e2330e7..0016170 100644 (file)
@@ -244,6 +244,7 @@ static int ks_sa_rng_probe(struct platform_device *pdev)
        ret = pm_runtime_get_sync(dev);
        if (ret < 0) {
                dev_err(dev, "Failed to enable SA power-domain\n");
+               pm_runtime_put_noidle(dev);
                pm_runtime_disable(dev);
                return ret;
        }
index 31cae88..934c92d 100644 (file)
@@ -171,7 +171,7 @@ static ssize_t read_mem(struct file *file, char __user *buf,
                        if (!ptr)
                                goto failed;
 
-                       probe = probe_kernel_read(bounce, ptr, sz);
+                       probe = copy_from_kernel_nofault(bounce, ptr, sz);
                        unxlate_dev_mem_ptr(p, ptr);
                        if (probe)
                                goto failed;
index a62f228..bc35aa0 100644 (file)
@@ -147,7 +147,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API
        select HW_RANDOM
        help
          Selecting this will register the SEC4 hardware rng to
-         the hw_random API for suppying the kernel entropy pool.
+         the hw_random API for supplying the kernel entropy pool.
 
 endif # CRYPTO_DEV_FSL_CAAM_JR
 
index 4fcdd26..f3d20b7 100644 (file)
@@ -54,7 +54,7 @@ static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
 
                /*
                 * load 1 to clear written reg:
-                * resets the done interrrupt and returns the RNG to idle.
+                * resets the done interrupt and returns the RNG to idle.
                 */
                append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
 
@@ -156,7 +156,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
                                     DESC_DER_DECO_STAT_SHIFT;
 
                /*
-                * If an error occured in the descriptor, then
+                * If an error occurred in the descriptor, then
                 * the DECO status field will be set to 0x0D
                 */
                if (deco_state == DECO_STAT_HOST_ERR)
@@ -264,7 +264,7 @@ static void devm_deinstantiate_rng(void *data)
  *        - -ENODEV if DECO0 couldn't be acquired
  *        - -EAGAIN if an error occurred when executing the descriptor
  *           f.i. there was a RNG hardware error due to not "good enough"
- *           entropy being aquired.
+ *           entropy being acquired.
  */
 static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
                           int gen_sk)
@@ -733,8 +733,8 @@ static int caam_probe(struct platform_device *pdev)
        handle_imx6_err005766(&ctrl->mcr);
 
        /*
-        *  Read the Compile Time paramters and SCFGR to determine
-        * if Virtualization is enabled for this platform
+        *  Read the Compile Time parameters and SCFGR to determine
+        * if virtualization is enabled for this platform
         */
        scfgr = rd_reg32(&ctrl->scfgr);
 
@@ -863,9 +863,9 @@ static int caam_probe(struct platform_device *pdev)
                        }
                        /*
                         * if instantiate_rng(...) fails, the loop will rerun
-                        * and the kick_trng(...) function will modfiy the
+                        * and the kick_trng(...) function will modify the
                         * upper and lower limits of the entropy sampling
-                        * interval, leading to a sucessful initialization of
+                        * interval, leading to a successful initialization of
                         * the RNG.
                         */
                        ret = instantiate_rng(dev, inst_handles,
@@ -882,8 +882,8 @@ static int caam_probe(struct platform_device *pdev)
                        return ret;
                }
                /*
-                * Set handles init'ed by this module as the complement of the
-                * already initialized ones
+                * Set handles initialized by this module as the complement of
+                * the already initialized ones
                 */
                ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_MASK;
 
index e796d3c..e134709 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #define SEC4_SG_LEN_EXT                0x80000000      /* Entry points to table */
-#define SEC4_SG_LEN_FIN                0x40000000      /* Last ent in table */
+#define SEC4_SG_LEN_FIN                0x40000000      /* Last entry in table */
 #define SEC4_SG_BPID_MASK      0x000000ff
 #define SEC4_SG_BPID_SHIFT     16
 #define SEC4_SG_LEN_MASK       0x3fffffff      /* Excludes EXT and FINAL */
  */
 #define HDR_REVERSE            0x00000800
 
-/* Propogate DNR property to SharedDesc */
+/* Propagate DNR property to SharedDesc */
 #define HDR_PROP_DNR           0x00000800
 
 /* JobDesc/SharedDesc share property */
index 68c1fd5..8ccc220 100644 (file)
@@ -453,7 +453,7 @@ struct srtp_decap_pdb {
 #define DSA_PDB_N_MASK         0x7f
 
 struct dsa_sign_pdb {
-       u32 sgf_ln; /* Use DSA_PDB_ defintions per above */
+       u32 sgf_ln; /* Use DSA_PDB_ definitions per above */
        u8 *q;
        u8 *r;
        u8 *g;  /* or Gx,y */
index a242633..476113e 100644 (file)
@@ -376,6 +376,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
        struct sev_device *sev = psp_master->sev_data;
        struct sev_user_data_pek_csr input;
        struct sev_data_pek_csr *data;
+       void __user *input_address;
        void *blob = NULL;
        int ret;
 
@@ -394,6 +395,7 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable)
                goto cmd;
 
        /* allocate a physically contiguous buffer to store the CSR blob */
+       input_address = (void __user *)input.address;
        if (input.length > SEV_FW_BLOB_MAX_SIZE) {
                ret = -EFAULT;
                goto e_free;
@@ -426,7 +428,7 @@ cmd:
        }
 
        if (blob) {
-               if (copy_to_user((void __user *)input.address, blob, input.length))
+               if (copy_to_user(input_address, blob, input.length))
                        ret = -EFAULT;
        }
 
@@ -437,7 +439,7 @@ e_free:
        return ret;
 }
 
-void *psp_copy_user_blob(u64 __user uaddr, u32 len)
+void *psp_copy_user_blob(u64 uaddr, u32 len)
 {
        if (!uaddr || !len)
                return ERR_PTR(-EINVAL);
@@ -446,7 +448,7 @@ void *psp_copy_user_blob(u64 __user uaddr, u32 len)
        if (len > SEV_FW_BLOB_MAX_SIZE)
                return ERR_PTR(-EINVAL);
 
-       return memdup_user((void __user *)(uintptr_t)uaddr, len);
+       return memdup_user((void __user *)uaddr, len);
 }
 EXPORT_SYMBOL_GPL(psp_copy_user_blob);
 
@@ -621,6 +623,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
 {
        struct sev_user_data_get_id2 input;
        struct sev_data_get_id *data;
+       void __user *input_address;
        void *id_blob = NULL;
        int ret;
 
@@ -631,6 +634,8 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
        if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
                return -EFAULT;
 
+       input_address = (void __user *)input.address;
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -660,8 +665,7 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp)
        }
 
        if (id_blob) {
-               if (copy_to_user((void __user *)input.address,
-                                id_blob, data->len)) {
+               if (copy_to_user(input_address, id_blob, data->len)) {
                        ret = -EFAULT;
                        goto e_free;
                }
@@ -720,6 +724,8 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
        struct sev_user_data_pdh_cert_export input;
        void *pdh_blob = NULL, *cert_blob = NULL;
        struct sev_data_pdh_cert_export *data;
+       void __user *input_cert_chain_address;
+       void __user *input_pdh_cert_address;
        int ret;
 
        /* If platform is not in INIT state then transition it to INIT. */
@@ -745,6 +751,9 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable)
            !input.cert_chain_address)
                goto cmd;
 
+       input_pdh_cert_address = (void __user *)input.pdh_cert_address;
+       input_cert_chain_address = (void __user *)input.cert_chain_address;
+
        /* Allocate a physically contiguous buffer to store the PDH blob. */
        if (input.pdh_cert_len > SEV_FW_BLOB_MAX_SIZE) {
                ret = -EFAULT;
@@ -788,7 +797,7 @@ cmd:
        }
 
        if (pdh_blob) {
-               if (copy_to_user((void __user *)input.pdh_cert_address,
+               if (copy_to_user(input_pdh_cert_address,
                                 pdh_blob, input.pdh_cert_len)) {
                        ret = -EFAULT;
                        goto e_free_cert;
@@ -796,7 +805,7 @@ cmd:
        }
 
        if (cert_blob) {
-               if (copy_to_user((void __user *)input.cert_chain_address,
+               if (copy_to_user(input_cert_chain_address,
                                 cert_blob, input.cert_chain_len))
                        ret = -EFAULT;
        }
index b3fdbdc..31e427e 100644 (file)
@@ -223,7 +223,7 @@ struct chcr_authenc_ctx {
 
 struct __aead_ctx {
        struct chcr_gcm_ctx gcm[0];
-       struct chcr_authenc_ctx authenc[0];
+       struct chcr_authenc_ctx authenc[];
 };
 
 struct chcr_aead_ctx {
@@ -235,7 +235,7 @@ struct chcr_aead_ctx {
        u8 nonce[4];
        u16 hmac_ctrl;
        u16 mayverify;
-       struct  __aead_ctx ctx[0];
+       struct  __aead_ctx ctx[];
 };
 
 struct hmac_ctx {
@@ -247,7 +247,7 @@ struct hmac_ctx {
 struct __crypto_ctx {
        struct hmac_ctx hmacctx[0];
        struct ablk_ctx ablkctx[0];
-       struct chcr_aead_ctx aeadctx[0];
+       struct chcr_aead_ctx aeadctx[];
 };
 
 struct chcr_context {
@@ -257,7 +257,7 @@ struct chcr_context {
        unsigned int  ntxq;
        unsigned int  nrxq;
        struct completion cbc_aes_aio_done;
-       struct __crypto_ctx crypto_ctx[0];
+       struct __crypto_ctx crypto_ctx[];
 };
 
 struct chcr_hctx_per_wr {
index 0e8c7e3..725a739 100644 (file)
@@ -66,7 +66,8 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev,
 
        sgl_size = sizeof(struct acc_hw_sge) * sge_nr +
                   sizeof(struct hisi_acc_hw_sgl);
-       block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1));
+       block_size = 1 << (PAGE_SHIFT + MAX_ORDER <= 32 ?
+                          PAGE_SHIFT + MAX_ORDER - 1 : 31);
        sgl_num_per_block = block_size / sgl_size;
        block_num = count / sgl_num_per_block;
        remain_sgl = count % sgl_num_per_block;
index 60e744f..1e0a1d7 100644 (file)
@@ -118,6 +118,9 @@ static void otx_cpt_aead_callback(int status, void *arg1, void *arg2)
        struct otx_cpt_req_info *cpt_req;
        struct pci_dev *pdev;
 
+       if (!cpt_info)
+               goto complete;
+
        cpt_req = cpt_info->req;
        if (!status) {
                /*
@@ -129,10 +132,10 @@ static void otx_cpt_aead_callback(int status, void *arg1, void *arg2)
                    !cpt_req->is_enc)
                        status = validate_hmac_cipher_null(cpt_req);
        }
-       if (cpt_info) {
-               pdev = cpt_info->pdev;
-               do_request_cleanup(pdev, cpt_info);
-       }
+       pdev = cpt_info->pdev;
+       do_request_cleanup(pdev, cpt_info);
+
+complete:
        if (areq)
                areq->complete(areq, status);
 }
index c9aa15f..193b40e 100644 (file)
@@ -135,7 +135,8 @@ int __init dio_find(int deviceid)
                else
                        va = ioremap(pa, PAGE_SIZE);
 
-                if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) {
+               if (copy_from_kernel_nofault(&i,
+                               (unsigned char *)va + DIO_IDOFF, 1)) {
                        if (scode >= DIOII_SCBASE)
                                iounmap(va);
                         continue;             /* no board present at that select code */
@@ -208,7 +209,8 @@ static int __init dio_init(void)
                else
                        va = ioremap(pa, PAGE_SIZE);
 
-                if (probe_kernel_read(&i, (unsigned char *)va + DIO_IDOFF, 1)) {
+               if (copy_from_kernel_nofault(&i,
+                               (unsigned char *)va + DIO_IDOFF, 1)) {
                        if (scode >= DIOII_SCBASE)
                                iounmap(va);
                         continue;              /* no board present at that select code */
index 8853d44..a8cfb59 100644 (file)
@@ -77,7 +77,7 @@ struct milbeaut_hdmac_device {
        struct dma_device ddev;
        struct clk *clk;
        void __iomem *reg_base;
-       struct milbeaut_hdmac_chan channels[0];
+       struct milbeaut_hdmac_chan channels[];
 };
 
 static struct milbeaut_hdmac_chan *
index ab3d2f3..85a5972 100644 (file)
@@ -74,7 +74,7 @@ struct milbeaut_xdmac_chan {
 struct milbeaut_xdmac_device {
        struct dma_device ddev;
        void __iomem *reg_base;
-       struct milbeaut_xdmac_chan channels[0];
+       struct milbeaut_xdmac_chan channels[];
 };
 
 static struct milbeaut_xdmac_chan *
index 4ab493d..347146a 100644 (file)
@@ -127,7 +127,7 @@ struct moxart_desc {
        unsigned int                    dma_cycles;
        struct virt_dma_desc            vd;
        uint8_t                         es;
-       struct moxart_sg                sg[0];
+       struct moxart_sg                sg[];
 };
 
 struct moxart_chan {
index b9f0d96..55fc740 100644 (file)
@@ -225,7 +225,7 @@ struct tegra_dma {
        u32                             global_pause_count;
 
        /* Last member of the structure */
-       struct tegra_dma_channel channels[0];
+       struct tegra_dma_channel channels[];
 };
 
 static inline void tdma_write(struct tegra_dma *tdma, u32 reg, u32 val)
index c4a5c17..35d81bd 100644 (file)
@@ -211,7 +211,7 @@ struct edma_desc {
        u32                             residue;
        u32                             residue_stat;
 
-       struct edma_pset                pset[0];
+       struct edma_pset                pset[];
 };
 
 struct edma_cc;
index 945b7c6..c91e2dc 100644 (file)
@@ -170,7 +170,7 @@ struct udma_desc {
        void *metadata; /* pointer to provided metadata buffer (EPIP, PSdata) */
 
        unsigned int hwdesc_count;
-       struct udma_hwdesc hwdesc[0];
+       struct udma_hwdesc hwdesc[];
 };
 
 enum udma_chan_state {
index 3938269..68e48bf 100644 (file)
@@ -88,7 +88,7 @@ struct timb_dma {
        struct dma_device       dma;
        void __iomem            *membase;
        struct tasklet_struct   tasklet;
-       struct timb_dma_chan    channels[0];
+       struct timb_dma_chan    channels[];
 };
 
 static struct device *chan2dev(struct dma_chan *chan)
index c7ea4f2..fb6c651 100644 (file)
@@ -117,7 +117,7 @@ struct inbound_transaction_resource {
 struct descriptor_resource {
        struct client_resource resource;
        struct fw_descriptor descriptor;
-       u32 data[0];
+       u32 data[];
 };
 
 struct iso_resource {
index 404a035..439d918 100644 (file)
@@ -620,7 +620,7 @@ struct fw_request {
        u32 request_header[4];
        int ack;
        u32 length;
-       u32 data[0];
+       u32 data[];
 };
 
 static void free_response_callback(struct fw_packet *packet,
index 4b0e4ee..71d5f16 100644 (file)
@@ -191,7 +191,7 @@ struct fw_node {
        /* Upper layer specific data. */
        void *data;
 
-       struct fw_node *ports[0];
+       struct fw_node *ports[];
 };
 
 static inline struct fw_node *fw_node_get(struct fw_node *node)
index 6ca2f5a..5fd6a60 100644 (file)
@@ -52,7 +52,7 @@ struct pcl {
 
 struct packet {
        unsigned int length;
-       char data[0];
+       char data[];
 };
 
 struct packet_buffer {
index 3326931..54fdc39 100644 (file)
@@ -111,7 +111,7 @@ struct descriptor_buffer {
        dma_addr_t buffer_bus;
        size_t buffer_size;
        size_t used;
-       struct descriptor buffer[0];
+       struct descriptor buffer[];
 };
 
 struct context {
index b618002..8b8127f 100644 (file)
@@ -262,7 +262,7 @@ struct dmi_system_event_log {
        u8      header_format;
        u8      type_descriptors_supported_count;
        u8      per_log_type_descriptor_length;
-       u8      supported_log_type_descriptos[0];
+       u8      supported_log_type_descriptos[];
 } __packed;
 
 #define DMI_SYSFS_SEL_FIELD(_field) \
index fd7f0fb..d17e4d6 100644 (file)
@@ -21,7 +21,7 @@
 struct cbmem_cons {
        u32 size_dont_access_after_boot;
        u32 cursor;
-       u8  body[0];
+       u8  body[];
 } __packed;
 
 #define CURSOR_MASK ((1 << 28) - 1)
index db08122..d23c5c6 100644 (file)
@@ -32,7 +32,7 @@ struct vpd_cbmem {
        u32 version;
        u32 ro_size;
        u32 rw_size;
-       u8  blob[0];
+       u8  blob[];
 };
 
 struct vpd_section {
index 96758b7..7127a04 100644 (file)
@@ -104,7 +104,7 @@ struct ibft_control {
        u16 tgt0_off;
        u16 nic1_off;
        u16 tgt1_off;
-       u16 expansion[0];
+       u16 expansion[];
 } __attribute__((__packed__));
 
 struct ibft_initiator {
index ce75d1d..e025405 100644 (file)
@@ -103,6 +103,6 @@ struct pcdp {
        u8                      creator_id[4];
        u32                     creator_rev;
        u32                     num_uarts;
-       struct pcdp_uart        uart[0];        /* actual size is num_uarts */
+       struct pcdp_uart        uart[]; /* actual size is num_uarts */
        /* remainder of table is pcdp_device structures */
 } __attribute__((packed));
index 775e389..16596a9 100644 (file)
@@ -696,7 +696,7 @@ static ssize_t amdgpu_set_pp_table(struct device *dev,
  * default power levels, write "r" (reset) to the file to reset them.
  *
  *
- * < For Vega20 >
+ * < For Vega20 and newer ASICs >
  *
  * Reading the file will display:
  *
@@ -1668,7 +1668,7 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
 }
 
 /**
- * DOC: busy_percent
+ * DOC: gpu_busy_percent
  *
  * The amdgpu driver provides a sysfs API for reading how busy the GPU
  * is as a percentage.  The file gpu_busy_percent is used for this.
index f0587d9..fee6092 100644 (file)
@@ -40,6 +40,7 @@
 #include <drm/drm_file.h>
 #include <drm/drm_drv.h>
 #include <drm/drm_device.h>
+#include <drm/drm_ioctl.h>
 #include <kgd_kfd_interface.h>
 #include <linux/swap.h>
 
@@ -1076,7 +1077,7 @@ static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
 #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
        struct drm_device *ddev = kfd->ddev;
 
-       return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major,
+       return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR,
                                          ddev->render->index,
                                          DEVCG_ACC_WRITE | DEVCG_ACC_READ);
 #else
index 3f66868..ea29cf9 100644 (file)
@@ -28,8 +28,6 @@ endif
 endif
 
 CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc_dpi.o := $(dsc_ccflags)
-CFLAGS_$(AMDDALPATH)/dc/dsc/dc_dsc.o := $(dsc_ccflags)
 
 DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o
 
index 0ea6662..0c7f247 100644 (file)
  * Author: AMD
  */
 
+#include <drm/drm_dsc.h>
 #include "dc_hw_types.h"
 #include "dsc.h"
 #include <drm/drm_dp_helper.h>
 #include "dc.h"
+#include "rc_calc.h"
 
 /* This module's internal functions */
 
@@ -304,22 +306,6 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
        return (value + 9) / 10;
 }
 
-static inline uint32_t calc_dsc_bpp_x16(uint32_t stream_bandwidth_kbps, uint32_t pix_clk_100hz, uint32_t bpp_increment_div)
-{
-       uint32_t dsc_target_bpp_x16;
-       float f_dsc_target_bpp;
-       float f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f;
-       uint32_t precision = bpp_increment_div; // bpp_increment_div is actually precision
-
-       f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz;
-
-       // Round down to the nearest precision stop to bring it into DSC spec range
-       dsc_target_bpp_x16 = (uint32_t)(f_dsc_target_bpp * precision);
-       dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision;
-
-       return dsc_target_bpp_x16;
-}
-
 /* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock
  * and uncompressed bandwidth.
  */
index 03ae159..667afbc 100644 (file)
@@ -23,6 +23,7 @@
  * Authors: AMD
  *
  */
+#include <drm/drm_dsc.h>
 
 #include "os_types.h"
 #include "rc_calc.h"
@@ -40,7 +41,8 @@
        break
 
 
-void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, enum max_min max_min, float bpp)
+static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc,
+                      enum max_min max_min, float bpp)
 {
        int mode = MODE_SELECT(444, 422, 420);
        int sel = table_hash(mode, bpc, max_min);
@@ -85,7 +87,7 @@ void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, enum ma
        memcpy(qps, table[index].qps, sizeof(qp_set));
 }
 
-double dsc_roundf(double num)
+static double dsc_roundf(double num)
 {
        if (num < 0.0)
                num = num - 0.5;
@@ -95,7 +97,7 @@ double dsc_roundf(double num)
        return (int)(num);
 }
 
-double dsc_ceil(double num)
+static double dsc_ceil(double num)
 {
        double retval = (int)num;
 
@@ -105,7 +107,7 @@ double dsc_ceil(double num)
        return (int)retval;
 }
 
-void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
+static void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
 {
        int   *p = ofs;
 
@@ -160,7 +162,7 @@ void get_ofs_set(qp_set ofs, enum colour_mode mode, float bpp)
        }
 }
 
-int median3(int a, int b, int c)
+static int median3(int a, int b, int c)
 {
        if (a > b)
                swap(a, b);
@@ -172,13 +174,25 @@ int median3(int a, int b, int c)
        return b;
 }
 
-void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_comp bpc, float bpp, int slice_width, int slice_height, int minor_version)
+static void _do_calc_rc_params(struct rc_params *rc, enum colour_mode cm,
+                              enum bits_per_comp bpc, u8 drm_bpp,
+                              bool is_navite_422_or_420,
+                              int slice_width, int slice_height,
+                              int minor_version)
 {
+       float bpp;
        float bpp_group;
        float initial_xmit_delay_factor;
        int padding_pixels;
        int i;
 
+       bpp = ((float)drm_bpp / 16.0);
+       /* in native_422 or native_420 modes, the bits_per_pixel is double the
+        * target bpp (the latter is what calc_rc_params expects)
+        */
+       if (is_navite_422_or_420)
+               bpp /= 2.0;
+
        rc->rc_quant_incr_limit0 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
        rc->rc_quant_incr_limit1 = ((bpc == BPC_8) ? 11 : (bpc == BPC_10 ? 15 : 19)) - ((minor_version == 1 && cm == CM_444) ? 1 : 0);
 
@@ -251,3 +265,128 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com
        rc->rc_buf_thresh[13] = 8064;
 }
 
+static u32 _do_bytes_per_pixel_calc(int slice_width, u8 drm_bpp,
+                                   bool is_navite_422_or_420)
+{
+       float bpp;
+       u32 bytes_per_pixel;
+       double d_bytes_per_pixel;
+
+       bpp = ((float)drm_bpp / 16.0);
+       d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
+       // TODO: Make sure the formula for calculating this is precise (ceiling
+       // vs. floor, and at what point they should be applied)
+       if (is_navite_422_or_420)
+               d_bytes_per_pixel /= 2;
+
+       bytes_per_pixel = (u32)dsc_ceil(d_bytes_per_pixel * 0x10000000);
+
+       return bytes_per_pixel;
+}
+
+static u32 _do_calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
+                               u32 bpp_increment_div)
+{
+       u32 dsc_target_bpp_x16;
+       float f_dsc_target_bpp;
+       float f_stream_bandwidth_100bps;
+       // bpp_increment_div is actually precision
+       u32 precision = bpp_increment_div;
+
+       f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f;
+       f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz;
+
+       // Round down to the nearest precision stop to bring it into DSC spec
+       // range
+       dsc_target_bpp_x16 = (u32)(f_dsc_target_bpp * precision);
+       dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision;
+
+       return dsc_target_bpp_x16;
+}
+
+/**
+ * calc_rc_params - reads the user's cmdline mode
+ * @rc: DC internal DSC parameters
+ * @pps: DRM struct with all required DSC values
+ *
+ * This function expects a drm_dsc_config data struct with all the required DSC
+ * values previously filled out by our driver and based on this information it
+ * computes some of the DSC values.
+ *
+ * @note This calculation requires float point operation, most of it executes
+ * under kernel_fpu_{begin,end}.
+ */
+void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps)
+{
+       enum colour_mode mode;
+       enum bits_per_comp bpc;
+       bool is_navite_422_or_420;
+       u8 drm_bpp = pps->bits_per_pixel;
+       int slice_width  = pps->slice_width;
+       int slice_height = pps->slice_height;
+
+       mode = pps->convert_rgb ? CM_RGB : (pps->simple_422  ? CM_444 :
+                                          (pps->native_422  ? CM_422 :
+                                           pps->native_420  ? CM_420 : CM_444));
+       bpc = (pps->bits_per_component == 8) ? BPC_8 : (pps->bits_per_component == 10)
+                                            ? BPC_10 : BPC_12;
+
+       is_navite_422_or_420 = pps->native_422 || pps->native_420;
+
+       DC_FP_START();
+       _do_calc_rc_params(rc, mode, bpc, drm_bpp, is_navite_422_or_420,
+                          slice_width, slice_height,
+                          pps->dsc_version_minor);
+       DC_FP_END();
+}
+
+/**
+ * calc_dsc_bytes_per_pixel - calculate bytes per pixel
+ * @pps: DRM struct with all required DSC values
+ *
+ * Based on the information inside drm_dsc_config, this function calculates the
+ * total of bytes per pixel.
+ *
+ * @note This calculation requires float point operation, most of it executes
+ * under kernel_fpu_{begin,end}.
+ *
+ * Return:
+ * Return the number of bytes per pixel
+ */
+u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps)
+
+{
+       u32 ret;
+       u8 drm_bpp = pps->bits_per_pixel;
+       int slice_width  = pps->slice_width;
+       bool is_navite_422_or_420 = pps->native_422 || pps->native_420;
+
+       DC_FP_START();
+       ret = _do_bytes_per_pixel_calc(slice_width, drm_bpp,
+                                      is_navite_422_or_420);
+       DC_FP_END();
+       return ret;
+}
+
+/**
+ * calc_dsc_bpp_x16 - retrieve the dsc bits per pixel
+ * @stream_bandwidth_kbps:
+ * @pix_clk_100hz:
+ * @bpp_increment_div:
+ *
+ * Calculate the total of bits per pixel for DSC configuration.
+ *
+ * @note This calculation requires float point operation, most of it executes
+ * under kernel_fpu_{begin,end}.
+ */
+u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
+                    u32 bpp_increment_div)
+{
+       u32 dsc_bpp;
+
+       DC_FP_START();
+       dsc_bpp =  _do_calc_dsc_bpp_x16(stream_bandwidth_kbps, pix_clk_100hz,
+                                       bpp_increment_div);
+       DC_FP_END();
+       return dsc_bpp;
+}
index b6b1f09..21723fa 100644 (file)
@@ -77,7 +77,10 @@ struct qp_entry {
 
 typedef struct qp_entry qp_table[];
 
-void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_comp bpc, float bpp, int slice_width, int slice_height, int minor_version);
+void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps);
+u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
+u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
+                    u32 bpp_increment_div);
 
 #endif
 
index 1f6e63b..ef830ad 100644 (file)
@@ -27,8 +27,6 @@
 #include "dscc_types.h"
 #include "rc_calc.h"
 
-double dsc_ceil(double num);
-
 static void copy_pps_fields(struct drm_dsc_config *to, const struct drm_dsc_config *from)
 {
        to->line_buf_depth           = from->line_buf_depth;
@@ -100,34 +98,13 @@ static void copy_rc_to_cfg(struct drm_dsc_config *dsc_cfg, const struct rc_param
 
 int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_parameters *dsc_params)
 {
-       enum colour_mode  mode = pps->convert_rgb ? CM_RGB :
-                                                       (pps->simple_422  ? CM_444 :
-                                                       (pps->native_422  ? CM_422 :
-                                                       pps->native_420  ? CM_420 : CM_444));
-       enum bits_per_comp bpc = (pps->bits_per_component == 8) ? BPC_8 :
-                                                       (pps->bits_per_component == 10) ? BPC_10 : BPC_12;
-       float            bpp = ((float) pps->bits_per_pixel / 16.0);
-       int              slice_width  = pps->slice_width;
-       int              slice_height = pps->slice_height;
        int              ret;
        struct rc_params rc;
        struct drm_dsc_config   dsc_cfg;
 
-       double d_bytes_per_pixel = dsc_ceil(bpp * slice_width / 8.0) / slice_width;
-
-       // TODO: Make sure the formula for calculating this is precise (ceiling vs. floor, and at what point they should be applied)
-       if (pps->native_422 || pps->native_420)
-               d_bytes_per_pixel /= 2;
-
-       dsc_params->bytes_per_pixel = (uint32_t)dsc_ceil(d_bytes_per_pixel * 0x10000000);
-
-       /* in native_422 or native_420 modes, the bits_per_pixel is double the target bpp
-        * (the latter is what calc_rc_params expects)
-        */
-       if (pps->native_422 || pps->native_420)
-               bpp /= 2.0;
+       dsc_params->bytes_per_pixel = calc_dsc_bytes_per_pixel(pps);
 
-       calc_rc_params(&rc, mode, bpc, bpp, slice_width, slice_height, pps->dsc_version_minor);
+       calc_rc_params(&rc, pps);
        dsc_params->pps = *pps;
        dsc_params->pps.initial_scale_value = 8 * rc.rc_model_size / (rc.rc_model_size - rc.initial_fullness_offset);
 
index 9431b48..bcfe34e 100644 (file)
@@ -843,7 +843,7 @@ static bool build_regamma(struct pwl_float_data_ex *rgb_regamma,
        pow_buffer_ptr = -1; // reset back to no optimize
        ret = true;
 release:
-       kfree(coeff);
+       kvfree(coeff);
        return ret;
 }
 
@@ -1777,7 +1777,7 @@ bool calculate_user_regamma_ramp(struct dc_transfer_func *output_tf,
 
        kfree(rgb_regamma);
 rgb_regamma_alloc_fail:
-       kvfree(rgb_user);
+       kfree(rgb_user);
 rgb_user_alloc_fail:
        return ret;
 }
index 85e5b1e..56923a9 100644 (file)
@@ -239,7 +239,7 @@ static void ci_initialize_power_tune_defaults(struct pp_hwmgr *hwmgr)
 
        switch (dev_id) {
        case 0x67BA:
-       case 0x66B1:
+       case 0x67B1:
                smu_data->power_tune_defaults = &defaults_hawaii_pro;
                break;
        case 0x67B8:
index cf80438..e464429 100644 (file)
@@ -61,13 +61,8 @@ int drm_i2c_encoder_init(struct drm_device *dev,
 
        request_module("%s%s", I2C_MODULE_PREFIX, info->type);
 
-       client = i2c_new_device(adap, info);
-       if (!client) {
-               err = -ENOMEM;
-               goto fail;
-       }
-
-       if (!client->dev.driver) {
+       client = i2c_new_client_device(adap, info);
+       if (!i2c_client_has_driver(client)) {
                err = -ENODEV;
                goto fail_unregister;
        }
@@ -84,7 +79,7 @@ int drm_i2c_encoder_init(struct drm_device *dev,
 
        err = encoder_drv->encoder_init(client, dev, encoder);
        if (err)
-               goto fail_unregister;
+               goto fail_module_put;
 
        if (info->platform_data)
                encoder->slave_funcs->set_config(&encoder->base,
@@ -92,10 +87,10 @@ int drm_i2c_encoder_init(struct drm_device *dev,
 
        return 0;
 
+fail_module_put:
+       module_put(module);
 fail_unregister:
        i2c_unregister_device(client);
-       module_put(module);
-fail:
        return err;
 }
 EXPORT_SYMBOL(drm_i2c_encoder_init);
index aa22465..0575a1e 100644 (file)
@@ -2579,14 +2579,14 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
 
 static void
 tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
-                               u32 level)
+                               u32 level, enum intel_output_type type)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
        const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
        u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
 
-       if (encoder->type == INTEL_OUTPUT_HDMI) {
+       if (type == INTEL_OUTPUT_HDMI) {
                n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
                ddi_translations = tgl_dkl_phy_hdmi_ddi_trans;
        } else {
@@ -2638,7 +2638,7 @@ static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
        if (intel_phy_is_combo(dev_priv, phy))
                icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
        else
-               tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level);
+               tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type);
 }
 
 static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
@@ -2987,7 +2987,7 @@ icl_program_mg_dp_mode(struct intel_digital_port *intel_dig_port,
                ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port));
        }
 
-       ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X1_MODE);
+       ln0 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
        ln1 &= ~(MG_DP_MODE_CFG_DP_X1_MODE | MG_DP_MODE_CFG_DP_X2_MODE);
 
        /* DPPATC */
@@ -3472,7 +3472,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
                                          INTEL_OUTPUT_DP_MST);
        enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
 
-       intel_dp_set_infoframes(encoder, false, old_crtc_state, old_conn_state);
+       if (!is_mst)
+               intel_dp_set_infoframes(encoder, false,
+                                       old_crtc_state, old_conn_state);
 
        /*
         * Power down sink before disabling the port, otherwise we end
index d18b406..f29e51c 100644 (file)
@@ -397,6 +397,14 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
         */
        drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
                                     false);
+
+       /*
+        * BSpec 4287: disable DIP after the transcoder is disabled and before
+        * the transcoder clock select is set to none.
+        */
+       if (last_mst_stream)
+               intel_dp_set_infoframes(&intel_dig_port->base, false,
+                                       old_crtc_state, NULL);
        /*
         * From TGL spec: "If multi-stream slave transcoder: Configure
         * Transcoder Clock Select to direct no clock to the transcoder"
index da5b610..8691eb6 100644 (file)
@@ -646,7 +646,7 @@ static int engine_setup_common(struct intel_engine_cs *engine)
 struct measure_breadcrumb {
        struct i915_request rq;
        struct intel_ring ring;
-       u32 cs[1024];
+       u32 cs[2048];
 };
 
 static int measure_breadcrumb_dw(struct intel_context *ce)
@@ -668,6 +668,8 @@ static int measure_breadcrumb_dw(struct intel_context *ce)
 
        frame->ring.vaddr = frame->cs;
        frame->ring.size = sizeof(frame->cs);
+       frame->ring.wrap =
+               BITS_PER_TYPE(frame->ring.size) - ilog2(frame->ring.size);
        frame->ring.effective_size = frame->ring.size;
        intel_ring_update_space(&frame->ring);
        frame->rq.ring = &frame->ring;
index 87e6c5b..7c3d8ef 100644 (file)
@@ -1134,6 +1134,13 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
                        list_move(&rq->sched.link, pl);
                        set_bit(I915_FENCE_FLAG_PQUEUE, &rq->fence.flags);
 
+                       /* Check in case we rollback so far we wrap [size/2] */
+                       if (intel_ring_direction(rq->ring,
+                                                intel_ring_wrap(rq->ring,
+                                                                rq->tail),
+                                                rq->ring->tail) > 0)
+                               rq->context->lrc.desc |= CTX_DESC_FORCE_RESTORE;
+
                        active = rq;
                } else {
                        struct intel_engine_cs *owner = rq->context->engine;
@@ -1498,8 +1505,9 @@ static u64 execlists_update_context(struct i915_request *rq)
         * HW has a tendency to ignore us rewinding the TAIL to the end of
         * an earlier request.
         */
+       GEM_BUG_ON(ce->lrc_reg_state[CTX_RING_TAIL] != rq->ring->tail);
+       prev = rq->ring->tail;
        tail = intel_ring_set_tail(rq->ring, rq->tail);
-       prev = ce->lrc_reg_state[CTX_RING_TAIL];
        if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0))
                desc |= CTX_DESC_FORCE_RESTORE;
        ce->lrc_reg_state[CTX_RING_TAIL] = tail;
@@ -1895,7 +1903,8 @@ static void defer_active(struct intel_engine_cs *engine)
 
 static bool
 need_timeslice(const struct intel_engine_cs *engine,
-              const struct i915_request *rq)
+              const struct i915_request *rq,
+              const struct rb_node *rb)
 {
        int hint;
 
@@ -1903,9 +1912,28 @@ need_timeslice(const struct intel_engine_cs *engine,
                return false;
 
        hint = engine->execlists.queue_priority_hint;
+
+       if (rb) {
+               const struct virtual_engine *ve =
+                       rb_entry(rb, typeof(*ve), nodes[engine->id].rb);
+               const struct intel_engine_cs *inflight =
+                       intel_context_inflight(&ve->context);
+
+               if (!inflight || inflight == engine) {
+                       struct i915_request *next;
+
+                       rcu_read_lock();
+                       next = READ_ONCE(ve->request);
+                       if (next)
+                               hint = max(hint, rq_prio(next));
+                       rcu_read_unlock();
+               }
+       }
+
        if (!list_is_last(&rq->sched.link, &engine->active.requests))
                hint = max(hint, rq_prio(list_next_entry(rq, sched.link)));
 
+       GEM_BUG_ON(hint >= I915_PRIORITY_UNPREEMPTABLE);
        return hint >= effective_prio(rq);
 }
 
@@ -1977,10 +2005,9 @@ static void set_timeslice(struct intel_engine_cs *engine)
        set_timer_ms(&engine->execlists.timer, duration);
 }
 
-static void start_timeslice(struct intel_engine_cs *engine)
+static void start_timeslice(struct intel_engine_cs *engine, int prio)
 {
        struct intel_engine_execlists *execlists = &engine->execlists;
-       const int prio = queue_prio(execlists);
        unsigned long duration;
 
        if (!intel_engine_has_timeslices(engine))
@@ -2140,7 +2167,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                        __unwind_incomplete_requests(engine);
 
                        last = NULL;
-               } else if (need_timeslice(engine, last) &&
+               } else if (need_timeslice(engine, last, rb) &&
                           timeslice_expired(execlists, last)) {
                        if (i915_request_completed(last)) {
                                tasklet_hi_schedule(&execlists->tasklet);
@@ -2188,7 +2215,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                                 * Even if ELSP[1] is occupied and not worthy
                                 * of timeslices, our queue might be.
                                 */
-                               start_timeslice(engine);
+                               start_timeslice(engine, queue_prio(execlists));
                                return;
                        }
                }
@@ -2223,7 +2250,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
 
                        if (last && !can_merge_rq(last, rq)) {
                                spin_unlock(&ve->base.active.lock);
-                               start_timeslice(engine);
+                               start_timeslice(engine, rq_prio(rq));
                                return; /* leave this for another sibling */
                        }
 
@@ -4739,6 +4766,14 @@ static int gen12_emit_flush(struct i915_request *request, u32 mode)
        return 0;
 }
 
+static void assert_request_valid(struct i915_request *rq)
+{
+       struct intel_ring *ring __maybe_unused = rq->ring;
+
+       /* Can we unwind this request without appearing to go forwards? */
+       GEM_BUG_ON(intel_ring_direction(ring, rq->wa_tail, rq->head) <= 0);
+}
+
 /*
  * Reserve space for 2 NOOPs at the end of each request to be
  * used as a workaround for not being allowed to do lite
@@ -4751,6 +4786,9 @@ static u32 *gen8_emit_wa_tail(struct i915_request *request, u32 *cs)
        *cs++ = MI_NOOP;
        request->wa_tail = intel_ring_offset(request, cs);
 
+       /* Check that entire request is less than half the ring */
+       assert_request_valid(request);
+
        return cs;
 }
 
index 8cda1b7..bdb3241 100644 (file)
@@ -315,3 +315,7 @@ int intel_ring_cacheline_align(struct i915_request *rq)
        GEM_BUG_ON(rq->ring->emit & (CACHELINE_BYTES - 1));
        return 0;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_ring.c"
+#endif
index 90a2b9e..85d2bef 100644 (file)
@@ -178,6 +178,12 @@ wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 set)
        wa_write_masked_or(wal, reg, set, set);
 }
 
+static void
+wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, u32 clr)
+{
+       wa_write_masked_or(wal, reg, clr, 0);
+}
+
 static void
 wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
 {
@@ -686,6 +692,227 @@ int intel_engine_emit_ctx_wa(struct i915_request *rq)
        return 0;
 }
 
+static void
+gen4_gt_workarounds_init(struct drm_i915_private *i915,
+                        struct i915_wa_list *wal)
+{
+       /* WaDisable_RenderCache_OperationalFlush:gen4,ilk */
+       wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);
+}
+
+static void
+g4x_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       gen4_gt_workarounds_init(i915, wal);
+
+       /* WaDisableRenderCachePipelinedFlush:g4x,ilk */
+       wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE);
+}
+
+static void
+ilk_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       g4x_gt_workarounds_init(i915, wal);
+
+       wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED);
+}
+
+static void
+snb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       /* WaDisableHiZPlanesWhenMSAAEnabled:snb */
+       wa_masked_en(wal,
+                    _3D_CHICKEN,
+                    _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB);
+
+       /* WaDisable_RenderCache_OperationalFlush:snb */
+       wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);
+
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       wa_add(wal,
+              GEN6_GT_MODE, 0,
+              _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4),
+              GEN6_WIZ_HASHING_16x4);
+
+       wa_masked_dis(wal, CACHE_MODE_0, CM0_STC_EVICT_DISABLE_LRA_SNB);
+
+       wa_masked_en(wal,
+                    _3D_CHICKEN3,
+                    /* WaStripsFansDisableFastClipPerformanceFix:snb */
+                    _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL |
+                    /*
+                     * Bspec says:
+                     * "This bit must be set if 3DSTATE_CLIP clip mode is set
+                     * to normal and 3DSTATE_SF number of SF output attributes
+                     * is more than 16."
+                     */
+                  _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH);
+}
+
+static void
+ivb_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       /* WaDisableEarlyCull:ivb */
+       wa_masked_en(wal, _3D_CHICKEN3, _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);
+
+       /* WaDisablePSDDualDispatchEnable:ivb */
+       if (IS_IVB_GT1(i915))
+               wa_masked_en(wal,
+                            GEN7_HALF_SLICE_CHICKEN1,
+                            GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
+
+       /* WaDisable_RenderCache_OperationalFlush:ivb */
+       wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE);
+
+       /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
+       wa_masked_dis(wal,
+                     GEN7_COMMON_SLICE_CHICKEN1,
+                     GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+       /* WaApplyL3ControlAndL3ChickenMode:ivb */
+       wa_write(wal, GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL);
+       wa_write(wal, GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
+
+       /* WaForceL3Serialization:ivb */
+       wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);
+
+       /*
+        * WaVSThreadDispatchOverride:ivb,vlv
+        *
+        * This actually overrides the dispatch
+        * mode for all thread types.
+        */
+       wa_write_masked_or(wal, GEN7_FF_THREAD_MODE,
+                          GEN7_FF_SCHED_MASK,
+                          GEN7_FF_TS_SCHED_HW |
+                          GEN7_FF_VS_SCHED_HW |
+                          GEN7_FF_DS_SCHED_HW);
+
+       if (0) { /* causes HiZ corruption on ivb:gt1 */
+               /* enable HiZ Raw Stall Optimization */
+               wa_masked_dis(wal, CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
+       }
+
+       /* WaDisable4x2SubspanOptimization:ivb */
+       wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
+
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       wa_add(wal, GEN7_GT_MODE, 0,
+              _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4),
+              GEN6_WIZ_HASHING_16x4);
+}
+
+static void
+vlv_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       /* WaDisableEarlyCull:vlv */
+       wa_masked_en(wal, _3D_CHICKEN3, _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);
+
+       /* WaPsdDispatchEnable:vlv */
+       /* WaDisablePSDDualDispatchEnable:vlv */
+       wa_masked_en(wal,
+                    GEN7_HALF_SLICE_CHICKEN1,
+                    GEN7_MAX_PS_THREAD_DEP |
+                    GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
+
+       /* WaDisable_RenderCache_OperationalFlush:vlv */
+       wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE);
+
+       /* WaForceL3Serialization:vlv */
+       wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);
+
+       /*
+        * WaVSThreadDispatchOverride:ivb,vlv
+        *
+        * This actually overrides the dispatch
+        * mode for all thread types.
+        */
+       wa_write_masked_or(wal,
+                          GEN7_FF_THREAD_MODE,
+                          GEN7_FF_SCHED_MASK,
+                          GEN7_FF_TS_SCHED_HW |
+                          GEN7_FF_VS_SCHED_HW |
+                          GEN7_FF_DS_SCHED_HW);
+
+       /*
+        * BSpec says this must be set, even though
+        * WaDisable4x2SubspanOptimization isn't listed for VLV.
+        */
+       wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
+
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       wa_add(wal, GEN7_GT_MODE, 0,
+              _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4),
+              GEN6_WIZ_HASHING_16x4);
+
+       /*
+        * WaIncreaseL3CreditsForVLVB0:vlv
+        * This is the hardware default actually.
+        */
+       wa_write(wal, GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);
+}
+
+static void
+hsw_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
+{
+       /* L3 caching of data atomics doesn't work -- disable it. */
+       wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
+
+       wa_add(wal,
+              HSW_ROW_CHICKEN3, 0,
+              _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),
+               0 /* XXX does this reg exist? */);
+
+       /* WaVSRefCountFullforceMissDisable:hsw */
+       wa_write_clr(wal, GEN7_FF_THREAD_MODE, GEN7_FF_VS_REF_CNT_FFME);
+
+       wa_masked_dis(wal,
+                     CACHE_MODE_0_GEN7,
+                     /* WaDisable_RenderCache_OperationalFlush:hsw */
+                     RC_OP_FLUSH_ENABLE |
+                     /* enable HiZ Raw Stall Optimization */
+                     HIZ_RAW_STALL_OPT_DISABLE);
+
+       /* WaDisable4x2SubspanOptimization:hsw */
+       wa_masked_en(wal, CACHE_MODE_1, PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
+
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       wa_add(wal, GEN7_GT_MODE, 0,
+              _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4),
+              GEN6_WIZ_HASHING_16x4);
+
+       /* WaSampleCChickenBitEnable:hsw */
+       wa_masked_en(wal, HALF_SLICE_CHICKEN3, HSW_SAMPLE_C_PERFORMANCE);
+}
+
 static void
 gen9_gt_workarounds_init(struct drm_i915_private *i915, struct i915_wa_list *wal)
 {
@@ -963,6 +1190,20 @@ gt_init_workarounds(struct drm_i915_private *i915, struct i915_wa_list *wal)
                bxt_gt_workarounds_init(i915, wal);
        else if (IS_SKYLAKE(i915))
                skl_gt_workarounds_init(i915, wal);
+       else if (IS_HASWELL(i915))
+               hsw_gt_workarounds_init(i915, wal);
+       else if (IS_VALLEYVIEW(i915))
+               vlv_gt_workarounds_init(i915, wal);
+       else if (IS_IVYBRIDGE(i915))
+               ivb_gt_workarounds_init(i915, wal);
+       else if (IS_GEN(i915, 6))
+               snb_gt_workarounds_init(i915, wal);
+       else if (IS_GEN(i915, 5))
+               ilk_gt_workarounds_init(i915, wal);
+       else if (IS_G4X(i915))
+               g4x_gt_workarounds_init(i915, wal);
+       else if (IS_GEN(i915, 4))
+               gen4_gt_workarounds_init(i915, wal);
        else if (INTEL_GEN(i915) <= 8)
                return;
        else
index 2b2efff..4aa4cc9 100644 (file)
@@ -310,22 +310,20 @@ static bool wait_until_running(struct hang *h, struct i915_request *rq)
                          1000));
 }
 
-static void engine_heartbeat_disable(struct intel_engine_cs *engine,
-                                    unsigned long *saved)
+static void engine_heartbeat_disable(struct intel_engine_cs *engine)
 {
-       *saved = engine->props.heartbeat_interval_ms;
        engine->props.heartbeat_interval_ms = 0;
 
        intel_engine_pm_get(engine);
        intel_engine_park_heartbeat(engine);
 }
 
-static void engine_heartbeat_enable(struct intel_engine_cs *engine,
-                                   unsigned long saved)
+static void engine_heartbeat_enable(struct intel_engine_cs *engine)
 {
        intel_engine_pm_put(engine);
 
-       engine->props.heartbeat_interval_ms = saved;
+       engine->props.heartbeat_interval_ms =
+               engine->defaults.heartbeat_interval_ms;
 }
 
 static int igt_hang_sanitycheck(void *arg)
@@ -473,7 +471,6 @@ static int igt_reset_nop_engine(void *arg)
        for_each_engine(engine, gt, id) {
                unsigned int reset_count, reset_engine_count, count;
                struct intel_context *ce;
-               unsigned long heartbeat;
                IGT_TIMEOUT(end_time);
                int err;
 
@@ -485,7 +482,7 @@ static int igt_reset_nop_engine(void *arg)
                reset_engine_count = i915_reset_engine_count(global, engine);
                count = 0;
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
                set_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
                do {
                        int i;
@@ -529,7 +526,7 @@ static int igt_reset_nop_engine(void *arg)
                        }
                } while (time_before(jiffies, end_time));
                clear_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
 
                pr_info("%s(%s): %d resets\n", __func__, engine->name, count);
 
@@ -564,7 +561,6 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active)
 
        for_each_engine(engine, gt, id) {
                unsigned int reset_count, reset_engine_count;
-               unsigned long heartbeat;
                IGT_TIMEOUT(end_time);
 
                if (active && !intel_engine_can_store_dword(engine))
@@ -580,7 +576,7 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active)
                reset_count = i915_reset_count(global);
                reset_engine_count = i915_reset_engine_count(global, engine);
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
                set_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
                do {
                        if (active) {
@@ -632,7 +628,7 @@ static int __igt_reset_engine(struct intel_gt *gt, bool active)
                        }
                } while (time_before(jiffies, end_time));
                clear_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
 
                if (err)
                        break;
@@ -789,7 +785,6 @@ static int __igt_reset_engines(struct intel_gt *gt,
                struct active_engine threads[I915_NUM_ENGINES] = {};
                unsigned long device = i915_reset_count(global);
                unsigned long count = 0, reported;
-               unsigned long heartbeat;
                IGT_TIMEOUT(end_time);
 
                if (flags & TEST_ACTIVE &&
@@ -832,7 +827,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
 
                yield(); /* start all threads before we begin */
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
                set_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
                do {
                        struct i915_request *rq = NULL;
@@ -906,7 +901,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
                        }
                } while (time_before(jiffies, end_time));
                clear_bit(I915_RESET_ENGINE + id, &gt->reset.flags);
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
 
                pr_info("i915_reset_engine(%s:%s): %lu resets\n",
                        engine->name, test_name, count);
index 824f99c..924bc01 100644 (file)
@@ -51,22 +51,20 @@ static struct i915_vma *create_scratch(struct intel_gt *gt)
        return vma;
 }
 
-static void engine_heartbeat_disable(struct intel_engine_cs *engine,
-                                    unsigned long *saved)
+static void engine_heartbeat_disable(struct intel_engine_cs *engine)
 {
-       *saved = engine->props.heartbeat_interval_ms;
        engine->props.heartbeat_interval_ms = 0;
 
        intel_engine_pm_get(engine);
        intel_engine_park_heartbeat(engine);
 }
 
-static void engine_heartbeat_enable(struct intel_engine_cs *engine,
-                                   unsigned long saved)
+static void engine_heartbeat_enable(struct intel_engine_cs *engine)
 {
        intel_engine_pm_put(engine);
 
-       engine->props.heartbeat_interval_ms = saved;
+       engine->props.heartbeat_interval_ms =
+               engine->defaults.heartbeat_interval_ms;
 }
 
 static bool is_active(struct i915_request *rq)
@@ -224,7 +222,6 @@ static int live_unlite_restore(struct intel_gt *gt, int prio)
                struct intel_context *ce[2] = {};
                struct i915_request *rq[2];
                struct igt_live_test t;
-               unsigned long saved;
                int n;
 
                if (prio && !intel_engine_has_preemption(engine))
@@ -237,7 +234,7 @@ static int live_unlite_restore(struct intel_gt *gt, int prio)
                        err = -EIO;
                        break;
                }
-               engine_heartbeat_disable(engine, &saved);
+               engine_heartbeat_disable(engine);
 
                for (n = 0; n < ARRAY_SIZE(ce); n++) {
                        struct intel_context *tmp;
@@ -345,7 +342,7 @@ err_ce:
                        intel_context_put(ce[n]);
                }
 
-               engine_heartbeat_enable(engine, saved);
+               engine_heartbeat_enable(engine);
                if (igt_live_test_end(&t))
                        err = -EIO;
                if (err)
@@ -466,7 +463,6 @@ static int live_hold_reset(void *arg)
 
        for_each_engine(engine, gt, id) {
                struct intel_context *ce;
-               unsigned long heartbeat;
                struct i915_request *rq;
 
                ce = intel_context_create(engine);
@@ -475,7 +471,7 @@ static int live_hold_reset(void *arg)
                        break;
                }
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
 
                rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK);
                if (IS_ERR(rq)) {
@@ -535,7 +531,7 @@ static int live_hold_reset(void *arg)
                i915_request_put(rq);
 
 out:
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
                intel_context_put(ce);
                if (err)
                        break;
@@ -580,10 +576,9 @@ static int live_error_interrupt(void *arg)
 
        for_each_engine(engine, gt, id) {
                const struct error_phase *p;
-               unsigned long heartbeat;
                int err = 0;
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
 
                for (p = phases; p->error[0] != GOOD; p++) {
                        struct i915_request *client[ARRAY_SIZE(phases->error)];
@@ -682,7 +677,7 @@ out:
                        }
                }
 
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
                if (err) {
                        intel_gt_set_wedged(gt);
                        return err;
@@ -828,7 +823,7 @@ slice_semaphore_queue(struct intel_engine_cs *outer,
                }
        }
 
-       err = release_queue(outer, vma, n, INT_MAX);
+       err = release_queue(outer, vma, n, I915_PRIORITY_BARRIER);
        if (err)
                goto out;
 
@@ -895,16 +890,14 @@ static int live_timeslice_preempt(void *arg)
                enum intel_engine_id id;
 
                for_each_engine(engine, gt, id) {
-                       unsigned long saved;
-
                        if (!intel_engine_has_preemption(engine))
                                continue;
 
                        memset(vaddr, 0, PAGE_SIZE);
 
-                       engine_heartbeat_disable(engine, &saved);
+                       engine_heartbeat_disable(engine);
                        err = slice_semaphore_queue(engine, vma, count);
-                       engine_heartbeat_enable(engine, saved);
+                       engine_heartbeat_enable(engine);
                        if (err)
                                goto err_pin;
 
@@ -1009,7 +1002,6 @@ static int live_timeslice_rewind(void *arg)
                enum { X = 1, Z, Y };
                struct i915_request *rq[3] = {};
                struct intel_context *ce;
-               unsigned long heartbeat;
                unsigned long timeslice;
                int i, err = 0;
                u32 *slot;
@@ -1028,7 +1020,7 @@ static int live_timeslice_rewind(void *arg)
                 * Expect execution/evaluation order XZY
                 */
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
                timeslice = xchg(&engine->props.timeslice_duration_ms, 1);
 
                slot = memset32(engine->status_page.addr + 1000, 0, 4);
@@ -1122,7 +1114,7 @@ err:
                wmb();
 
                engine->props.timeslice_duration_ms = timeslice;
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
                for (i = 0; i < 3; i++)
                        i915_request_put(rq[i]);
                if (igt_flush_test(gt->i915))
@@ -1202,12 +1194,11 @@ static int live_timeslice_queue(void *arg)
                        .priority = I915_USER_PRIORITY(I915_PRIORITY_MAX),
                };
                struct i915_request *rq, *nop;
-               unsigned long saved;
 
                if (!intel_engine_has_preemption(engine))
                        continue;
 
-               engine_heartbeat_disable(engine, &saved);
+               engine_heartbeat_disable(engine);
                memset(vaddr, 0, PAGE_SIZE);
 
                /* ELSP[0]: semaphore wait */
@@ -1284,7 +1275,7 @@ static int live_timeslice_queue(void *arg)
 err_rq:
                i915_request_put(rq);
 err_heartbeat:
-               engine_heartbeat_enable(engine, saved);
+               engine_heartbeat_enable(engine);
                if (err)
                        break;
        }
@@ -1298,6 +1289,121 @@ err_obj:
        return err;
 }
 
+static int live_timeslice_nopreempt(void *arg)
+{
+       struct intel_gt *gt = arg;
+       struct intel_engine_cs *engine;
+       enum intel_engine_id id;
+       struct igt_spinner spin;
+       int err = 0;
+
+       /*
+        * We should not timeslice into a request that is marked with
+        * I915_REQUEST_NOPREEMPT.
+        */
+       if (!IS_ACTIVE(CONFIG_DRM_I915_TIMESLICE_DURATION))
+               return 0;
+
+       if (igt_spinner_init(&spin, gt))
+               return -ENOMEM;
+
+       for_each_engine(engine, gt, id) {
+               struct intel_context *ce;
+               struct i915_request *rq;
+               unsigned long timeslice;
+
+               if (!intel_engine_has_preemption(engine))
+                       continue;
+
+               ce = intel_context_create(engine);
+               if (IS_ERR(ce)) {
+                       err = PTR_ERR(ce);
+                       break;
+               }
+
+               engine_heartbeat_disable(engine);
+               timeslice = xchg(&engine->props.timeslice_duration_ms, 1);
+
+               /* Create an unpreemptible spinner */
+
+               rq = igt_spinner_create_request(&spin, ce, MI_ARB_CHECK);
+               intel_context_put(ce);
+               if (IS_ERR(rq)) {
+                       err = PTR_ERR(rq);
+                       goto out_heartbeat;
+               }
+
+               i915_request_get(rq);
+               i915_request_add(rq);
+
+               if (!igt_wait_for_spinner(&spin, rq)) {
+                       i915_request_put(rq);
+                       err = -ETIME;
+                       goto out_spin;
+               }
+
+               set_bit(I915_FENCE_FLAG_NOPREEMPT, &rq->fence.flags);
+               i915_request_put(rq);
+
+               /* Followed by a maximum priority barrier (heartbeat) */
+
+               ce = intel_context_create(engine);
+               if (IS_ERR(ce)) {
+                       err = PTR_ERR(rq);
+                       goto out_spin;
+               }
+
+               rq = intel_context_create_request(ce);
+               intel_context_put(ce);
+               if (IS_ERR(rq)) {
+                       err = PTR_ERR(rq);
+                       goto out_spin;
+               }
+
+               rq->sched.attr.priority = I915_PRIORITY_BARRIER;
+               i915_request_get(rq);
+               i915_request_add(rq);
+
+               /*
+                * Wait until the barrier is in ELSP, and we know timeslicing
+                * will have been activated.
+                */
+               if (wait_for_submit(engine, rq, HZ / 2)) {
+                       i915_request_put(rq);
+                       err = -ETIME;
+                       goto out_spin;
+               }
+
+               /*
+                * Since the ELSP[0] request is unpreemptible, it should not
+                * allow the maximum priority barrier through. Wait long
+                * enough to see if it is timesliced in by mistake.
+                */
+               if (i915_request_wait(rq, 0, timeslice_threshold(engine)) >= 0) {
+                       pr_err("%s: I915_PRIORITY_BARRIER request completed, bypassing no-preempt request\n",
+                              engine->name);
+                       err = -EINVAL;
+               }
+               i915_request_put(rq);
+
+out_spin:
+               igt_spinner_end(&spin);
+out_heartbeat:
+               xchg(&engine->props.timeslice_duration_ms, timeslice);
+               engine_heartbeat_enable(engine);
+               if (err)
+                       break;
+
+               if (igt_flush_test(gt->i915)) {
+                       err = -EIO;
+                       break;
+               }
+       }
+
+       igt_spinner_fini(&spin);
+       return err;
+}
+
 static int live_busywait_preempt(void *arg)
 {
        struct intel_gt *gt = arg;
@@ -4153,7 +4259,6 @@ static int reset_virtual_engine(struct intel_gt *gt,
 {
        struct intel_engine_cs *engine;
        struct intel_context *ve;
-       unsigned long *heartbeat;
        struct igt_spinner spin;
        struct i915_request *rq;
        unsigned int n;
@@ -4165,15 +4270,9 @@ static int reset_virtual_engine(struct intel_gt *gt,
         * descendents are not executed while the capture is in progress.
         */
 
-       heartbeat = kmalloc_array(nsibling, sizeof(*heartbeat), GFP_KERNEL);
-       if (!heartbeat)
+       if (igt_spinner_init(&spin, gt))
                return -ENOMEM;
 
-       if (igt_spinner_init(&spin, gt)) {
-               err = -ENOMEM;
-               goto out_free;
-       }
-
        ve = intel_execlists_create_virtual(siblings, nsibling);
        if (IS_ERR(ve)) {
                err = PTR_ERR(ve);
@@ -4181,7 +4280,7 @@ static int reset_virtual_engine(struct intel_gt *gt,
        }
 
        for (n = 0; n < nsibling; n++)
-               engine_heartbeat_disable(siblings[n], &heartbeat[n]);
+               engine_heartbeat_disable(siblings[n]);
 
        rq = igt_spinner_create_request(&spin, ve, MI_ARB_CHECK);
        if (IS_ERR(rq)) {
@@ -4252,13 +4351,11 @@ out_rq:
        i915_request_put(rq);
 out_heartbeat:
        for (n = 0; n < nsibling; n++)
-               engine_heartbeat_enable(siblings[n], heartbeat[n]);
+               engine_heartbeat_enable(siblings[n]);
 
        intel_context_put(ve);
 out_spin:
        igt_spinner_fini(&spin);
-out_free:
-       kfree(heartbeat);
        return err;
 }
 
@@ -4314,6 +4411,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
                SUBTEST(live_timeslice_preempt),
                SUBTEST(live_timeslice_rewind),
                SUBTEST(live_timeslice_queue),
+               SUBTEST(live_timeslice_nopreempt),
                SUBTEST(live_busywait_preempt),
                SUBTEST(live_preempt),
                SUBTEST(live_late_preempt),
@@ -4932,9 +5030,7 @@ static int live_lrc_gpr(void *arg)
                return PTR_ERR(scratch);
 
        for_each_engine(engine, gt, id) {
-               unsigned long heartbeat;
-
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
 
                err = __live_lrc_gpr(engine, scratch, false);
                if (err)
@@ -4945,7 +5041,7 @@ static int live_lrc_gpr(void *arg)
                        goto err;
 
 err:
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
                if (igt_flush_test(gt->i915))
                        err = -EIO;
                if (err)
@@ -5092,10 +5188,9 @@ static int live_lrc_timestamp(void *arg)
         */
 
        for_each_engine(data.engine, gt, id) {
-               unsigned long heartbeat;
                int i, err = 0;
 
-               engine_heartbeat_disable(data.engine, &heartbeat);
+               engine_heartbeat_disable(data.engine);
 
                for (i = 0; i < ARRAY_SIZE(data.ce); i++) {
                        struct intel_context *tmp;
@@ -5128,7 +5223,7 @@ static int live_lrc_timestamp(void *arg)
                }
 
 err:
-               engine_heartbeat_enable(data.engine, heartbeat);
+               engine_heartbeat_enable(data.engine);
                for (i = 0; i < ARRAY_SIZE(data.ce); i++) {
                        if (!data.ce[i])
                                break;
index 8831ffe..63f87d8 100644 (file)
@@ -18,6 +18,20 @@ struct live_mocs {
        void *vaddr;
 };
 
+static struct intel_context *mocs_context_create(struct intel_engine_cs *engine)
+{
+       struct intel_context *ce;
+
+       ce = intel_context_create(engine);
+       if (IS_ERR(ce))
+               return ce;
+
+       /* We build large requests to read the registers from the ring */
+       ce->ring = __intel_context_ring_size(SZ_16K);
+
+       return ce;
+}
+
 static int request_add_sync(struct i915_request *rq, int err)
 {
        i915_request_get(rq);
@@ -301,7 +315,7 @@ static int live_mocs_clean(void *arg)
        for_each_engine(engine, gt, id) {
                struct intel_context *ce;
 
-               ce = intel_context_create(engine);
+               ce = mocs_context_create(engine);
                if (IS_ERR(ce)) {
                        err = PTR_ERR(ce);
                        break;
@@ -395,7 +409,7 @@ static int live_mocs_reset(void *arg)
        for_each_engine(engine, gt, id) {
                struct intel_context *ce;
 
-               ce = intel_context_create(engine);
+               ce = mocs_context_create(engine);
                if (IS_ERR(ce)) {
                        err = PTR_ERR(ce);
                        break;
diff --git a/drivers/gpu/drm/i915/gt/selftest_ring.c b/drivers/gpu/drm/i915/gt/selftest_ring.c
new file mode 100644 (file)
index 0000000..2a8c534
--- /dev/null
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright Â© 2020 Intel Corporation
+ */
+
+static struct intel_ring *mock_ring(unsigned long sz)
+{
+       struct intel_ring *ring;
+
+       ring = kzalloc(sizeof(*ring) + sz, GFP_KERNEL);
+       if (!ring)
+               return NULL;
+
+       kref_init(&ring->ref);
+       ring->size = sz;
+       ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(sz);
+       ring->effective_size = sz;
+       ring->vaddr = (void *)(ring + 1);
+       atomic_set(&ring->pin_count, 1);
+
+       intel_ring_update_space(ring);
+
+       return ring;
+}
+
+static void mock_ring_free(struct intel_ring *ring)
+{
+       kfree(ring);
+}
+
+static int check_ring_direction(struct intel_ring *ring,
+                               u32 next, u32 prev,
+                               int expected)
+{
+       int result;
+
+       result = intel_ring_direction(ring, next, prev);
+       if (result < 0)
+               result = -1;
+       else if (result > 0)
+               result = 1;
+
+       if (result != expected) {
+               pr_err("intel_ring_direction(%u, %u):%d != %d\n",
+                      next, prev, result, expected);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int check_ring_step(struct intel_ring *ring, u32 x, u32 step)
+{
+       u32 prev = x, next = intel_ring_wrap(ring, x + step);
+       int err = 0;
+
+       err |= check_ring_direction(ring, next, next,  0);
+       err |= check_ring_direction(ring, prev, prev,  0);
+       err |= check_ring_direction(ring, next, prev,  1);
+       err |= check_ring_direction(ring, prev, next, -1);
+
+       return err;
+}
+
+static int check_ring_offset(struct intel_ring *ring, u32 x, u32 step)
+{
+       int err = 0;
+
+       err |= check_ring_step(ring, x, step);
+       err |= check_ring_step(ring, intel_ring_wrap(ring, x + 1), step);
+       err |= check_ring_step(ring, intel_ring_wrap(ring, x - 1), step);
+
+       return err;
+}
+
+static int igt_ring_direction(void *dummy)
+{
+       struct intel_ring *ring;
+       unsigned int half = 2048;
+       int step, err = 0;
+
+       ring = mock_ring(2 * half);
+       if (!ring)
+               return -ENOMEM;
+
+       GEM_BUG_ON(ring->size != 2 * half);
+
+       /* Precision of wrap detection is limited to ring->size / 2 */
+       for (step = 1; step < half; step <<= 1) {
+               err |= check_ring_offset(ring, 0, step);
+               err |= check_ring_offset(ring, half, step);
+       }
+       err |= check_ring_step(ring, 0, half - 64);
+
+       /* And check unwrapped handling for good measure */
+       err |= check_ring_offset(ring, 0, 2 * half + 64);
+       err |= check_ring_offset(ring, 3 * half, 1);
+
+       mock_ring_free(ring);
+       return err;
+}
+
+int intel_ring_mock_selftests(void)
+{
+       static const struct i915_subtest tests[] = {
+               SUBTEST(igt_ring_direction),
+       };
+
+       return i915_subtests(tests, NULL);
+}
index 6275d69..5049c3d 100644 (file)
 /* Try to isolate the impact of cstates from determing frequency response */
 #define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */
 
-static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+static void engine_heartbeat_disable(struct intel_engine_cs *engine)
 {
-       unsigned long old;
-
-       old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+       engine->props.heartbeat_interval_ms = 0;
 
        intel_engine_pm_get(engine);
        intel_engine_park_heartbeat(engine);
-
-       return old;
 }
 
-static void engine_heartbeat_enable(struct intel_engine_cs *engine,
-                                   unsigned long saved)
+static void engine_heartbeat_enable(struct intel_engine_cs *engine)
 {
        intel_engine_pm_put(engine);
 
-       engine->props.heartbeat_interval_ms = saved;
+       engine->props.heartbeat_interval_ms =
+               engine->defaults.heartbeat_interval_ms;
 }
 
 static void dummy_rps_work(struct work_struct *wrk)
@@ -246,7 +242,6 @@ int live_rps_clock_interval(void *arg)
        intel_gt_check_clock_frequency(gt);
 
        for_each_engine(engine, gt, id) {
-               unsigned long saved_heartbeat;
                struct i915_request *rq;
                u32 cycles;
                u64 dt;
@@ -254,13 +249,13 @@ int live_rps_clock_interval(void *arg)
                if (!intel_engine_can_store_dword(engine))
                        continue;
 
-               saved_heartbeat = engine_heartbeat_disable(engine);
+               engine_heartbeat_disable(engine);
 
                rq = igt_spinner_create_request(&spin,
                                                engine->kernel_context,
                                                MI_NOOP);
                if (IS_ERR(rq)) {
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        err = PTR_ERR(rq);
                        break;
                }
@@ -271,7 +266,7 @@ int live_rps_clock_interval(void *arg)
                        pr_err("%s: RPS spinner did not start\n",
                               engine->name);
                        igt_spinner_end(&spin);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        intel_gt_set_wedged(engine->gt);
                        err = -EIO;
                        break;
@@ -327,7 +322,7 @@ int live_rps_clock_interval(void *arg)
                intel_uncore_forcewake_put(gt->uncore, FORCEWAKE_ALL);
 
                igt_spinner_end(&spin);
-               engine_heartbeat_enable(engine, saved_heartbeat);
+               engine_heartbeat_enable(engine);
 
                if (err == 0) {
                        u64 time = intel_gt_pm_interval_to_ns(gt, cycles);
@@ -405,7 +400,6 @@ int live_rps_control(void *arg)
 
        intel_gt_pm_get(gt);
        for_each_engine(engine, gt, id) {
-               unsigned long saved_heartbeat;
                struct i915_request *rq;
                ktime_t min_dt, max_dt;
                int f, limit;
@@ -414,7 +408,7 @@ int live_rps_control(void *arg)
                if (!intel_engine_can_store_dword(engine))
                        continue;
 
-               saved_heartbeat = engine_heartbeat_disable(engine);
+               engine_heartbeat_disable(engine);
 
                rq = igt_spinner_create_request(&spin,
                                                engine->kernel_context,
@@ -430,7 +424,7 @@ int live_rps_control(void *arg)
                        pr_err("%s: RPS spinner did not start\n",
                               engine->name);
                        igt_spinner_end(&spin);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        intel_gt_set_wedged(engine->gt);
                        err = -EIO;
                        break;
@@ -440,7 +434,7 @@ int live_rps_control(void *arg)
                        pr_err("%s: could not set minimum frequency [%x], only %x!\n",
                               engine->name, rps->min_freq, read_cagf(rps));
                        igt_spinner_end(&spin);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        show_pstate_limits(rps);
                        err = -EINVAL;
                        break;
@@ -457,7 +451,7 @@ int live_rps_control(void *arg)
                        pr_err("%s: could not restore minimum frequency [%x], only %x!\n",
                               engine->name, rps->min_freq, read_cagf(rps));
                        igt_spinner_end(&spin);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        show_pstate_limits(rps);
                        err = -EINVAL;
                        break;
@@ -472,7 +466,7 @@ int live_rps_control(void *arg)
                min_dt = ktime_sub(ktime_get(), min_dt);
 
                igt_spinner_end(&spin);
-               engine_heartbeat_enable(engine, saved_heartbeat);
+               engine_heartbeat_enable(engine);
 
                pr_info("%s: range:[%x:%uMHz, %x:%uMHz] limit:[%x:%uMHz], %x:%x response %lluns:%lluns\n",
                        engine->name,
@@ -635,7 +629,6 @@ int live_rps_frequency_cs(void *arg)
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
-               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct i915_vma *vma;
                u32 *cancel, *cntr;
@@ -644,14 +637,14 @@ int live_rps_frequency_cs(void *arg)
                        int freq;
                } min, max;
 
-               saved_heartbeat = engine_heartbeat_disable(engine);
+               engine_heartbeat_disable(engine);
 
                vma = create_spin_counter(engine,
                                          engine->kernel_context->vm, false,
                                          &cancel, &cntr);
                if (IS_ERR(vma)) {
                        err = PTR_ERR(vma);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        break;
                }
 
@@ -732,7 +725,7 @@ err_vma:
                i915_vma_unpin(vma);
                i915_vma_put(vma);
 
-               engine_heartbeat_enable(engine, saved_heartbeat);
+               engine_heartbeat_enable(engine);
                if (igt_flush_test(gt->i915))
                        err = -EIO;
                if (err)
@@ -778,7 +771,6 @@ int live_rps_frequency_srm(void *arg)
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
-               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct i915_vma *vma;
                u32 *cancel, *cntr;
@@ -787,14 +779,14 @@ int live_rps_frequency_srm(void *arg)
                        int freq;
                } min, max;
 
-               saved_heartbeat = engine_heartbeat_disable(engine);
+               engine_heartbeat_disable(engine);
 
                vma = create_spin_counter(engine,
                                          engine->kernel_context->vm, true,
                                          &cancel, &cntr);
                if (IS_ERR(vma)) {
                        err = PTR_ERR(vma);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        break;
                }
 
@@ -874,7 +866,7 @@ err_vma:
                i915_vma_unpin(vma);
                i915_vma_put(vma);
 
-               engine_heartbeat_enable(engine, saved_heartbeat);
+               engine_heartbeat_enable(engine);
                if (igt_flush_test(gt->i915))
                        err = -EIO;
                if (err)
@@ -1066,16 +1058,14 @@ int live_rps_interrupt(void *arg)
        for_each_engine(engine, gt, id) {
                /* Keep the engine busy with a spinner; expect an UP! */
                if (pm_events & GEN6_PM_RP_UP_THRESHOLD) {
-                       unsigned long saved_heartbeat;
-
                        intel_gt_pm_wait_for_idle(engine->gt);
                        GEM_BUG_ON(intel_rps_is_active(rps));
 
-                       saved_heartbeat = engine_heartbeat_disable(engine);
+                       engine_heartbeat_disable(engine);
 
                        err = __rps_up_interrupt(rps, engine, &spin);
 
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        if (err)
                                goto out;
 
@@ -1084,15 +1074,13 @@ int live_rps_interrupt(void *arg)
 
                /* Keep the engine awake but idle and check for DOWN */
                if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) {
-                       unsigned long saved_heartbeat;
-
-                       saved_heartbeat = engine_heartbeat_disable(engine);
+                       engine_heartbeat_disable(engine);
                        intel_rc6_disable(&gt->rc6);
 
                        err = __rps_down_interrupt(rps, engine);
 
                        intel_rc6_enable(&gt->rc6);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        if (err)
                                goto out;
                }
@@ -1168,7 +1156,6 @@ int live_rps_power(void *arg)
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
-               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct {
                        u64 power;
@@ -1178,13 +1165,13 @@ int live_rps_power(void *arg)
                if (!intel_engine_can_store_dword(engine))
                        continue;
 
-               saved_heartbeat = engine_heartbeat_disable(engine);
+               engine_heartbeat_disable(engine);
 
                rq = igt_spinner_create_request(&spin,
                                                engine->kernel_context,
                                                MI_NOOP);
                if (IS_ERR(rq)) {
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        err = PTR_ERR(rq);
                        break;
                }
@@ -1195,7 +1182,7 @@ int live_rps_power(void *arg)
                        pr_err("%s: RPS spinner did not start\n",
                               engine->name);
                        igt_spinner_end(&spin);
-                       engine_heartbeat_enable(engine, saved_heartbeat);
+                       engine_heartbeat_enable(engine);
                        intel_gt_set_wedged(engine->gt);
                        err = -EIO;
                        break;
@@ -1208,7 +1195,7 @@ int live_rps_power(void *arg)
                min.power = measure_power_at(rps, &min.freq);
 
                igt_spinner_end(&spin);
-               engine_heartbeat_enable(engine, saved_heartbeat);
+               engine_heartbeat_enable(engine);
 
                pr_info("%s: min:%llumW @ %uMHz, max:%llumW @ %uMHz\n",
                        engine->name,
index c2578a0..ef1c350 100644 (file)
@@ -751,22 +751,20 @@ out_free:
        return err;
 }
 
-static void engine_heartbeat_disable(struct intel_engine_cs *engine,
-                                    unsigned long *saved)
+static void engine_heartbeat_disable(struct intel_engine_cs *engine)
 {
-       *saved = engine->props.heartbeat_interval_ms;
        engine->props.heartbeat_interval_ms = 0;
 
        intel_engine_pm_get(engine);
        intel_engine_park_heartbeat(engine);
 }
 
-static void engine_heartbeat_enable(struct intel_engine_cs *engine,
-                                   unsigned long saved)
+static void engine_heartbeat_enable(struct intel_engine_cs *engine)
 {
        intel_engine_pm_put(engine);
 
-       engine->props.heartbeat_interval_ms = saved;
+       engine->props.heartbeat_interval_ms =
+               engine->defaults.heartbeat_interval_ms;
 }
 
 static int live_hwsp_rollover_kernel(void *arg)
@@ -785,10 +783,9 @@ static int live_hwsp_rollover_kernel(void *arg)
                struct intel_context *ce = engine->kernel_context;
                struct intel_timeline *tl = ce->timeline;
                struct i915_request *rq[3] = {};
-               unsigned long heartbeat;
                int i;
 
-               engine_heartbeat_disable(engine, &heartbeat);
+               engine_heartbeat_disable(engine);
                if (intel_gt_wait_for_idle(gt, HZ / 2)) {
                        err = -EIO;
                        goto out;
@@ -839,7 +836,7 @@ static int live_hwsp_rollover_kernel(void *arg)
 out:
                for (i = 0; i < ARRAY_SIZE(rq); i++)
                        i915_request_put(rq[i]);
-               engine_heartbeat_enable(engine, heartbeat);
+               engine_heartbeat_enable(engine);
                if (err)
                        break;
        }
index 5ed3232..3278546 100644 (file)
@@ -623,6 +623,8 @@ err_request:
                                err = -EINVAL;
                                goto out_unpin;
                        }
+               } else {
+                       rsvd = 0;
                }
 
                expect = results[0];
index 4dc601d..284cf07 100644 (file)
@@ -3125,6 +3125,7 @@ static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv)
 
        val = I915_READ(GEN11_DE_HPD_IMR);
        val &= ~hotplug_irqs;
+       val |= ~enabled_irqs & hotplug_irqs;
        I915_WRITE(GEN11_DE_HPD_IMR, val);
        POSTING_READ(GEN11_DE_HPD_IMR);
 
index e991a70..962ded9 100644 (file)
@@ -269,12 +269,48 @@ static bool exclusive_mmio_access(const struct drm_i915_private *i915)
        return IS_GEN(i915, 7);
 }
 
+static void engine_sample(struct intel_engine_cs *engine, unsigned int period_ns)
+{
+       struct intel_engine_pmu *pmu = &engine->pmu;
+       bool busy;
+       u32 val;
+
+       val = ENGINE_READ_FW(engine, RING_CTL);
+       if (val == 0) /* powerwell off => engine idle */
+               return;
+
+       if (val & RING_WAIT)
+               add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns);
+       if (val & RING_WAIT_SEMAPHORE)
+               add_sample(&pmu->sample[I915_SAMPLE_SEMA], period_ns);
+
+       /* No need to sample when busy stats are supported. */
+       if (intel_engine_supports_stats(engine))
+               return;
+
+       /*
+        * While waiting on a semaphore or event, MI_MODE reports the
+        * ring as idle. However, previously using the seqno, and with
+        * execlists sampling, we account for the ring waiting as the
+        * engine being busy. Therefore, we record the sample as being
+        * busy if either waiting or !idle.
+        */
+       busy = val & (RING_WAIT_SEMAPHORE | RING_WAIT);
+       if (!busy) {
+               val = ENGINE_READ_FW(engine, RING_MI_MODE);
+               busy = !(val & MODE_IDLE);
+       }
+       if (busy)
+               add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns);
+}
+
 static void
 engines_sample(struct intel_gt *gt, unsigned int period_ns)
 {
        struct drm_i915_private *i915 = gt->i915;
        struct intel_engine_cs *engine;
        enum intel_engine_id id;
+       unsigned long flags;
 
        if ((i915->pmu.enable & ENGINE_SAMPLE_MASK) == 0)
                return;
@@ -283,53 +319,17 @@ engines_sample(struct intel_gt *gt, unsigned int period_ns)
                return;
 
        for_each_engine(engine, gt, id) {
-               struct intel_engine_pmu *pmu = &engine->pmu;
-               spinlock_t *mmio_lock;
-               unsigned long flags;
-               bool busy;
-               u32 val;
-
                if (!intel_engine_pm_get_if_awake(engine))
                        continue;
 
-               mmio_lock = NULL;
-               if (exclusive_mmio_access(i915))
-                       mmio_lock = &engine->uncore->lock;
-
-               if (unlikely(mmio_lock))
-                       spin_lock_irqsave(mmio_lock, flags);
-
-               val = ENGINE_READ_FW(engine, RING_CTL);
-               if (val == 0) /* powerwell off => engine idle */
-                       goto skip;
-
-               if (val & RING_WAIT)
-                       add_sample(&pmu->sample[I915_SAMPLE_WAIT], period_ns);
-               if (val & RING_WAIT_SEMAPHORE)
-                       add_sample(&pmu->sample[I915_SAMPLE_SEMA], period_ns);
-
-               /* No need to sample when busy stats are supported. */
-               if (intel_engine_supports_stats(engine))
-                       goto skip;
-
-               /*
-                * While waiting on a semaphore or event, MI_MODE reports the
-                * ring as idle. However, previously using the seqno, and with
-                * execlists sampling, we account for the ring waiting as the
-                * engine being busy. Therefore, we record the sample as being
-                * busy if either waiting or !idle.
-                */
-               busy = val & (RING_WAIT_SEMAPHORE | RING_WAIT);
-               if (!busy) {
-                       val = ENGINE_READ_FW(engine, RING_MI_MODE);
-                       busy = !(val & MODE_IDLE);
+               if (exclusive_mmio_access(i915)) {
+                       spin_lock_irqsave(&engine->uncore->lock, flags);
+                       engine_sample(engine, period_ns);
+                       spin_unlock_irqrestore(&engine->uncore->lock, flags);
+               } else {
+                       engine_sample(engine, period_ns);
                }
-               if (busy)
-                       add_sample(&pmu->sample[I915_SAMPLE_BUSY], period_ns);
 
-skip:
-               if (unlikely(mmio_lock))
-                       spin_unlock_irqrestore(mmio_lock, flags);
                intel_engine_pm_put_async(engine);
        }
 }
index 5003a71..8aa7866 100644 (file)
@@ -42,7 +42,7 @@ enum {
  * active request.
  */
 #define I915_PRIORITY_UNPREEMPTABLE INT_MAX
-#define I915_PRIORITY_BARRIER INT_MAX
+#define I915_PRIORITY_BARRIER (I915_PRIORITY_UNPREEMPTABLE - 1)
 
 struct i915_priolist {
        struct list_head requests[I915_PRIORITY_COUNT];
index 7717581..06cd1d2 100644 (file)
@@ -7896,7 +7896,7 @@ enum {
 
 /* GEN7 chicken */
 #define GEN7_COMMON_SLICE_CHICKEN1             _MMIO(0x7010)
-  #define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC    ((1 << 10) | (1 << 26))
+  #define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC    (1 << 10)
   #define GEN9_RHWO_OPTIMIZATION_DISABLE       (1 << 14)
 
 #define COMMON_SLICE_CHICKEN2                                  _MMIO(0x7014)
index 696491d..07f663c 100644 (file)
@@ -6830,16 +6830,6 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv)
        I915_WRITE(ILK_DISPLAY_CHICKEN2,
                   I915_READ(ILK_DISPLAY_CHICKEN2) |
                   ILK_ELPIN_409_SELECT);
-       I915_WRITE(_3D_CHICKEN2,
-                  _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
-                  _3D_CHICKEN2_WM_READ_PIPELINED);
-
-       /* WaDisableRenderCachePipelinedFlush:ilk */
-       I915_WRITE(CACHE_MODE_0,
-                  _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:ilk */
-       I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
 
        g4x_disable_trickle_feed(dev_priv);
 
@@ -6902,27 +6892,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv)
                   I915_READ(ILK_DISPLAY_CHICKEN2) |
                   ILK_ELPIN_409_SELECT);
 
-       /* WaDisableHiZPlanesWhenMSAAEnabled:snb */
-       I915_WRITE(_3D_CHICKEN,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB));
-
-       /* WaDisable_RenderCache_OperationalFlush:snb */
-       I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
-
-       /*
-        * BSpec recoomends 8x4 when MSAA is used,
-        * however in practice 16x4 seems fastest.
-        *
-        * Note that PS/WM thread counts depend on the WIZ hashing
-        * disable bit, which we don't touch here, but it's good
-        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
-        */
-       I915_WRITE(GEN6_GT_MODE,
-                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
-
-       I915_WRITE(CACHE_MODE_0,
-                  _MASKED_BIT_DISABLE(CM0_STC_EVICT_DISABLE_LRA_SNB));
-
        I915_WRITE(GEN6_UCGCTL1,
                   I915_READ(GEN6_UCGCTL1) |
                   GEN6_BLBUNIT_CLOCK_GATE_DISABLE |
@@ -6945,18 +6914,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv)
                   GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
                   GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
 
-       /* WaStripsFansDisableFastClipPerformanceFix:snb */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL));
-
-       /*
-        * Bspec says:
-        * "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and
-        * 3DSTATE_SF number of SF output attributes is more than 16."
-        */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH));
-
        /*
         * According to the spec the following bits should be
         * set in order to enable memory self-refresh and fbc:
@@ -6986,24 +6943,6 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv)
        gen6_check_mch_setup(dev_priv);
 }
 
-static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
-{
-       u32 reg = I915_READ(GEN7_FF_THREAD_MODE);
-
-       /*
-        * WaVSThreadDispatchOverride:ivb,vlv
-        *
-        * This actually overrides the dispatch
-        * mode for all thread types.
-        */
-       reg &= ~GEN7_FF_SCHED_MASK;
-       reg |= GEN7_FF_TS_SCHED_HW;
-       reg |= GEN7_FF_VS_SCHED_HW;
-       reg |= GEN7_FF_DS_SCHED_HW;
-
-       I915_WRITE(GEN7_FF_THREAD_MODE, reg);
-}
-
 static void lpt_init_clock_gating(struct drm_i915_private *dev_priv)
 {
        /*
@@ -7230,45 +7169,10 @@ static void bdw_init_clock_gating(struct drm_i915_private *dev_priv)
 
 static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-       /* L3 caching of data atomics doesn't work -- disable it. */
-       I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
-       I915_WRITE(HSW_ROW_CHICKEN3,
-                  _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE));
-
        /* This is required by WaCatErrorRejectionIssue:hsw */
        I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
-                       I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
-                       GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
-
-       /* WaVSRefCountFullforceMissDisable:hsw */
-       I915_WRITE(GEN7_FF_THREAD_MODE,
-                  I915_READ(GEN7_FF_THREAD_MODE) & ~GEN7_FF_VS_REF_CNT_FFME);
-
-       /* WaDisable_RenderCache_OperationalFlush:hsw */
-       I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
-
-       /* enable HiZ Raw Stall Optimization */
-       I915_WRITE(CACHE_MODE_0_GEN7,
-                  _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
-
-       /* WaDisable4x2SubspanOptimization:hsw */
-       I915_WRITE(CACHE_MODE_1,
-                  _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
-
-       /*
-        * BSpec recommends 8x4 when MSAA is used,
-        * however in practice 16x4 seems fastest.
-        *
-        * Note that PS/WM thread counts depend on the WIZ hashing
-        * disable bit, which we don't touch here, but it's good
-        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
-        */
-       I915_WRITE(GEN7_GT_MODE,
-                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
-
-       /* WaSampleCChickenBitEnable:hsw */
-       I915_WRITE(HALF_SLICE_CHICKEN3,
-                  _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE));
+                  I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+                  GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
        /* WaSwitchSolVfFArbitrationPriority:hsw */
        I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
@@ -7282,32 +7186,11 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
 
        I915_WRITE(ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
 
-       /* WaDisableEarlyCull:ivb */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
-
        /* WaDisableBackToBackFlipFix:ivb */
        I915_WRITE(IVB_CHICKEN3,
                   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
                   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
-       /* WaDisablePSDDualDispatchEnable:ivb */
-       if (IS_IVB_GT1(dev_priv))
-               I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
-                          _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:ivb */
-       I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
-
-       /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
-       I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
-                  GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
-
-       /* WaApplyL3ControlAndL3ChickenMode:ivb */
-       I915_WRITE(GEN7_L3CNTLREG1,
-                       GEN7_WA_FOR_GEN7_L3_CONTROL);
-       I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
-                  GEN7_WA_L3_CHICKEN_MODE);
        if (IS_IVB_GT1(dev_priv))
                I915_WRITE(GEN7_ROW_CHICKEN2,
                           _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
@@ -7319,10 +7202,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
                           _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
        }
 
-       /* WaForceL3Serialization:ivb */
-       I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
-                  ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
-
        /*
         * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
         * This implements the WaDisableRCZUnitClockGating:ivb workaround.
@@ -7337,29 +7216,6 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
 
        g4x_disable_trickle_feed(dev_priv);
 
-       gen7_setup_fixed_func_scheduler(dev_priv);
-
-       if (0) { /* causes HiZ corruption on ivb:gt1 */
-               /* enable HiZ Raw Stall Optimization */
-               I915_WRITE(CACHE_MODE_0_GEN7,
-                          _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
-       }
-
-       /* WaDisable4x2SubspanOptimization:ivb */
-       I915_WRITE(CACHE_MODE_1,
-                  _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
-
-       /*
-        * BSpec recommends 8x4 when MSAA is used,
-        * however in practice 16x4 seems fastest.
-        *
-        * Note that PS/WM thread counts depend on the WIZ hashing
-        * disable bit, which we don't touch here, but it's good
-        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
-        */
-       I915_WRITE(GEN7_GT_MODE,
-                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
-
        snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
        snpcr &= ~GEN6_MBC_SNPCR_MASK;
        snpcr |= GEN6_MBC_SNPCR_MED;
@@ -7373,28 +7229,11 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
 
 static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-       /* WaDisableEarlyCull:vlv */
-       I915_WRITE(_3D_CHICKEN3,
-                  _MASKED_BIT_ENABLE(_3D_CHICKEN_SF_DISABLE_OBJEND_CULL));
-
        /* WaDisableBackToBackFlipFix:vlv */
        I915_WRITE(IVB_CHICKEN3,
                   CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
                   CHICKEN3_DGMG_DONE_FIX_DISABLE);
 
-       /* WaPsdDispatchEnable:vlv */
-       /* WaDisablePSDDualDispatchEnable:vlv */
-       I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
-                  _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP |
-                                     GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:vlv */
-       I915_WRITE(CACHE_MODE_0_GEN7, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
-
-       /* WaForceL3Serialization:vlv */
-       I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
-                  ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
-
        /* WaDisableDopClockGating:vlv */
        I915_WRITE(GEN7_ROW_CHICKEN2,
                   _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
@@ -7404,8 +7243,6 @@ static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
                   I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
                   GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
-       gen7_setup_fixed_func_scheduler(dev_priv);
-
        /*
         * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
         * This implements the WaDisableRCZUnitClockGating:vlv workaround.
@@ -7419,30 +7256,6 @@ static void vlv_init_clock_gating(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN7_UCGCTL4,
                   I915_READ(GEN7_UCGCTL4) | GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
 
-       /*
-        * BSpec says this must be set, even though
-        * WaDisable4x2SubspanOptimization isn't listed for VLV.
-        */
-       I915_WRITE(CACHE_MODE_1,
-                  _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
-
-       /*
-        * BSpec recommends 8x4 when MSAA is used,
-        * however in practice 16x4 seems fastest.
-        *
-        * Note that PS/WM thread counts depend on the WIZ hashing
-        * disable bit, which we don't touch here, but it's good
-        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
-        */
-       I915_WRITE(GEN7_GT_MODE,
-                  _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4));
-
-       /*
-        * WaIncreaseL3CreditsForVLVB0:vlv
-        * This is the hardware default actually.
-        */
-       I915_WRITE(GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);
-
        /*
         * WaDisableVLVClockGating_VBIIssue:vlv
         * Disable clock gating on th GCFG unit to prevent a delay
@@ -7495,13 +7308,6 @@ static void g4x_init_clock_gating(struct drm_i915_private *dev_priv)
                dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
        I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
 
-       /* WaDisableRenderCachePipelinedFlush */
-       I915_WRITE(CACHE_MODE_0,
-                  _MASKED_BIT_ENABLE(CM0_PIPELINED_RENDER_FLUSH_DISABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:g4x */
-       I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
-
        g4x_disable_trickle_feed(dev_priv);
 }
 
@@ -7517,11 +7323,6 @@ static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv)
        intel_uncore_write(uncore,
                           MI_ARB_STATE,
                           _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:gen4 */
-       intel_uncore_write(uncore,
-                          CACHE_MODE_0,
-                          _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
 }
 
 static void i965g_init_clock_gating(struct drm_i915_private *dev_priv)
@@ -7534,9 +7335,6 @@ static void i965g_init_clock_gating(struct drm_i915_private *dev_priv)
        I915_WRITE(RENCLK_GATE_D2, 0);
        I915_WRITE(MI_ARB_STATE,
                   _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE));
-
-       /* WaDisable_RenderCache_OperationalFlush:gen4 */
-       I915_WRITE(CACHE_MODE_0, _MASKED_BIT_DISABLE(RC_OP_FLUSH_ENABLE));
 }
 
 static void gen3_init_clock_gating(struct drm_i915_private *dev_priv)
index 6a2be7d..6090ce3 100644 (file)
@@ -21,6 +21,7 @@ selftest(fence, i915_sw_fence_mock_selftests)
 selftest(scatterlist, scatterlist_mock_selftests)
 selftest(syncmap, i915_syncmap_mock_selftests)
 selftest(uncore, intel_uncore_mock_selftests)
+selftest(ring, intel_ring_mock_selftests)
 selftest(engine, intel_engine_cs_mock_selftests)
 selftest(timelines, intel_timeline_mock_selftests)
 selftest(requests, i915_request_mock_selftests)
index 4f932a4..603b4a9 100644 (file)
@@ -34,7 +34,7 @@ struct stp_policy_node {
        unsigned int            first_channel;
        unsigned int            last_channel;
        /* this is the one that's exposed to the attributes */
-       unsigned char           priv[0];
+       unsigned char           priv[];
 };
 
 void *stp_policy_node_priv(struct stp_policy_node *pn)
index 3569439..a9be49f 100644 (file)
@@ -23,7 +23,7 @@ void *stp_policy_node_priv(struct stp_policy_node *pn);
 
 struct stp_master {
        unsigned int    nr_free;
-       unsigned long   chan_map[0];
+       unsigned long   chan_map[];
 };
 
 struct stm_device {
@@ -42,7 +42,7 @@ struct stm_device {
        const struct config_item_type           *pdrv_node_type;
        /* master allocation */
        spinlock_t              mc_lock;
-       struct stp_master       *masters[0];
+       struct stp_master       *masters[];
 };
 
 #define to_stm_device(_d)                              \
index d1f278f..26f03a1 100644 (file)
@@ -815,31 +815,6 @@ out_err_silent:
 }
 EXPORT_SYMBOL_GPL(i2c_new_client_device);
 
-/**
- * i2c_new_device - instantiate an i2c device
- * @adap: the adapter managing the device
- * @info: describes one I2C device; bus_num is ignored
- * Context: can sleep
- *
- * This deprecated function has the same functionality as
- * @i2c_new_client_device, it just returns NULL instead of an ERR_PTR in case of
- * an error for compatibility with current I2C API. It will be removed once all
- * users are converted.
- *
- * This returns the new i2c client, which may be saved for later use with
- * i2c_unregister_device(); or NULL to indicate an error.
- */
-struct i2c_client *
-i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
-{
-       struct i2c_client *ret;
-
-       ret = i2c_new_client_device(adap, info);
-       return IS_ERR(ret) ? NULL : ret;
-}
-EXPORT_SYMBOL_GPL(i2c_new_device);
-
-
 /**
  * i2c_unregister_device - reverse effect of i2c_new_*_device()
  * @client: value returned from i2c_new_*_device()
index b34d2ff..56bb840 100644 (file)
@@ -4,7 +4,7 @@
  *
  * This file contains the SMBus functions which are always included in the I2C
  * core because they can be emulated via I2C. SMBus specific extensions
- * (e.g. smbalert) are handled in a seperate i2c-smbus module.
+ * (e.g. smbalert) are handled in a separate i2c-smbus module.
  *
  * All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
  * SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
index 6542523..13eacf6 100644 (file)
@@ -1021,7 +1021,7 @@ static int __init hp_sdc_register(void)
        hp_sdc.base_io   = (unsigned long) 0xf0428000;
        hp_sdc.data_io   = (unsigned long) hp_sdc.base_io + 1;
        hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
-       if (!probe_kernel_read(&i, (unsigned char *)hp_sdc.data_io, 1))
+       if (!copy_from_kernel_nofault(&i, (unsigned char *)hp_sdc.data_io, 1))
                hp_sdc.dev = (void *)1;
        hp_sdc.dev_err   = hp_sdc_init();
 #endif
index 39de94e..6548a60 100644 (file)
@@ -1389,7 +1389,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
                        if (__set_blocks(n1, n1->keys + n2->keys,
                                         block_bytes(b->c)) >
                            btree_blocks(new_nodes[i]))
-                               goto out_nocoalesce;
+                               goto out_unlock_nocoalesce;
 
                        keys = n2->keys;
                        /* Take the key of the node we're getting rid of */
@@ -1418,7 +1418,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
 
                if (__bch_keylist_realloc(&keylist,
                                          bkey_u64s(&new_nodes[i]->key)))
-                       goto out_nocoalesce;
+                       goto out_unlock_nocoalesce;
 
                bch_btree_node_write(new_nodes[i], &cl);
                bch_keylist_add(&keylist, &new_nodes[i]->key);
@@ -1464,6 +1464,10 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op,
        /* Invalidated our iterator */
        return -EINTR;
 
+out_unlock_nocoalesce:
+       for (i = 0; i < nodes; i++)
+               mutex_unlock(&new_nodes[i]->write_lock);
+
 out_nocoalesce:
        closure_sync(&cl);
 
index f9975c2..2014016 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/genhd.h>
 #include <linux/idr.h>
 #include <linux/kthread.h>
+#include <linux/workqueue.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/reboot.h>
@@ -819,7 +820,8 @@ static void bcache_device_free(struct bcache_device *d)
 }
 
 static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
-                             sector_t sectors, make_request_fn make_request_fn)
+                             sector_t sectors, make_request_fn make_request_fn,
+                             struct block_device *cached_bdev)
 {
        struct request_queue *q;
        const size_t max_stripes = min_t(size_t, INT_MAX,
@@ -885,6 +887,20 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,
        q->limits.io_min                = block_size;
        q->limits.logical_block_size    = block_size;
        q->limits.physical_block_size   = block_size;
+
+       if (q->limits.logical_block_size > PAGE_SIZE && cached_bdev) {
+               /*
+                * This should only happen with BCACHE_SB_VERSION_BDEV.
+                * Block/page size is checked for BCACHE_SB_VERSION_CDEV.
+                */
+               pr_info("%s: sb/logical block size (%u) greater than page size (%lu) falling back to device logical block size (%u)\n",
+                       d->disk->disk_name, q->limits.logical_block_size,
+                       PAGE_SIZE, bdev_logical_block_size(cached_bdev));
+
+               /* This also adjusts physical block size/min io size if needed */
+               blk_queue_logical_block_size(q, bdev_logical_block_size(cached_bdev));
+       }
+
        blk_queue_flag_set(QUEUE_FLAG_NONROT, d->disk->queue);
        blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, d->disk->queue);
        blk_queue_flag_set(QUEUE_FLAG_DISCARD, d->disk->queue);
@@ -1340,7 +1356,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned int block_size)
 
        ret = bcache_device_init(&dc->disk, block_size,
                         dc->bdev->bd_part->nr_sects - dc->sb.data_offset,
-                        cached_dev_make_request);
+                        cached_dev_make_request, dc->bdev);
        if (ret)
                return ret;
 
@@ -1453,7 +1469,7 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u)
        kobject_init(&d->kobj, &bch_flash_dev_ktype);
 
        if (bcache_device_init(d, block_bytes(c), u->sectors,
-                       flash_dev_make_request))
+                       flash_dev_make_request, NULL))
                goto err;
 
        bcache_device_attach(d, c, u - c->uuids);
@@ -2364,7 +2380,7 @@ static bool bch_is_open(struct block_device *bdev)
 }
 
 struct async_reg_args {
-       struct work_struct reg_work;
+       struct delayed_work reg_work;
        char *path;
        struct cache_sb *sb;
        struct cache_sb_disk *sb_disk;
@@ -2375,7 +2391,7 @@ static void register_bdev_worker(struct work_struct *work)
 {
        int fail = false;
        struct async_reg_args *args =
-               container_of(work, struct async_reg_args, reg_work);
+               container_of(work, struct async_reg_args, reg_work.work);
        struct cached_dev *dc;
 
        dc = kzalloc(sizeof(*dc), GFP_KERNEL);
@@ -2405,7 +2421,7 @@ static void register_cache_worker(struct work_struct *work)
 {
        int fail = false;
        struct async_reg_args *args =
-               container_of(work, struct async_reg_args, reg_work);
+               container_of(work, struct async_reg_args, reg_work.work);
        struct cache *ca;
 
        ca = kzalloc(sizeof(*ca), GFP_KERNEL);
@@ -2433,11 +2449,12 @@ out:
 static void register_device_aync(struct async_reg_args *args)
 {
        if (SB_IS_BDEV(args->sb))
-               INIT_WORK(&args->reg_work, register_bdev_worker);
+               INIT_DELAYED_WORK(&args->reg_work, register_bdev_worker);
        else
-               INIT_WORK(&args->reg_work, register_cache_worker);
+               INIT_DELAYED_WORK(&args->reg_work, register_cache_worker);
 
-       queue_work(system_wq, &args->reg_work);
+       /* 10 jiffies is enough for a delay */
+       queue_delayed_work(system_wq, &args->reg_work, 10);
 }
 
 static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
index 3362962..b02a3c7 100644 (file)
@@ -193,7 +193,7 @@ struct pwc_raw_frame {
                                   decompressor) */
        __u8   cmd[4];          /* the four byte of the command (in case of
                                   nala, only the first 3 bytes is filled) */
-       __u8   rawframe[0];     /* frame_size = H / 4 * vbandlength */
+       __u8   rawframe[];      /* frame_size = H / 4 * vbandlength */
 } __packed;
 
 /* intermediate buffers with raw data from the USB cam */
index db8cdf5..e9cacc2 100644 (file)
@@ -412,6 +412,7 @@ MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id);
 
 static struct i2c_driver mt6360_pmu_driver = {
        .driver = {
+               .name = "mt6360_pmu",
                .pm = &mt6360_pmu_pm_ops,
                .of_match_table = of_match_ptr(mt6360_pmu_of_id),
        },
index bccd341..d5d2af4 100644 (file)
@@ -828,7 +828,7 @@ static void run_plant_and_detach_test(int is_early)
        char before[BREAK_INSTR_SIZE];
        char after[BREAK_INSTR_SIZE];
 
-       probe_kernel_read(before, (char *)kgdbts_break_test,
+       copy_from_kernel_nofault(before, (char *)kgdbts_break_test,
          BREAK_INSTR_SIZE);
        init_simple_test();
        ts.tst = plant_and_detach_test;
@@ -836,8 +836,8 @@ static void run_plant_and_detach_test(int is_early)
        /* Activate test with initial breakpoint */
        if (!is_early)
                kgdb_breakpoint();
-       probe_kernel_read(after, (char *)kgdbts_break_test,
-         BREAK_INSTR_SIZE);
+       copy_from_kernel_nofault(after, (char *)kgdbts_break_test,
+                       BREAK_INSTR_SIZE);
        if (memcmp(before, after, BREAK_INSTR_SIZE)) {
                printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n");
                panic("kgdb memory corruption");
index efd1a1d..5d3c691 100644 (file)
@@ -552,6 +552,8 @@ static int bareudp_validate(struct nlattr *tb[], struct nlattr *data[],
 static int bareudp2info(struct nlattr *data[], struct bareudp_conf *conf,
                        struct netlink_ext_ack *extack)
 {
+       memset(conf, 0, sizeof(*conf));
+
        if (!data[IFLA_BAREUDP_PORT]) {
                NL_SET_ERR_MSG(extack, "port not specified");
                return -EINVAL;
index d08a3d5..6ad83a8 100644 (file)
@@ -146,7 +146,7 @@ struct pciefd_rx_dma {
        __le32 irq_status;
        __le32 sys_time_low;
        __le32 sys_time_high;
-       struct pucan_rx_msg msg[0];
+       struct pucan_rx_msg msg[];
 } __packed __aligned(4);
 
 /* Tx Link record */
@@ -194,7 +194,7 @@ struct pciefd_board {
        struct pci_dev *pci_dev;
        int can_count;
        spinlock_t cmd_lock;            /* 64-bits cmds must be atomic */
-       struct pciefd_can *can[0];      /* array of network devices */
+       struct pciefd_can *can[];       /* array of network devices */
 };
 
 /* supported device ids. */
index bc0e47c..1771345 100644 (file)
@@ -891,16 +891,16 @@ void sja1105_ptp_txtstamp_skb(struct dsa_switch *ds, int port,
 
        mutex_lock(&ptp_data->lock);
 
-       rc = sja1105_ptpclkval_read(priv, &ticks, NULL);
+       rc = sja1105_ptpegr_ts_poll(ds, port, &ts);
        if (rc < 0) {
-               dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc);
+               dev_err(ds->dev, "timed out polling for tstamp\n");
                kfree_skb(skb);
                goto out;
        }
 
-       rc = sja1105_ptpegr_ts_poll(ds, port, &ts);
+       rc = sja1105_ptpclkval_read(priv, &ticks, NULL);
        if (rc < 0) {
-               dev_err(ds->dev, "timed out polling for tstamp\n");
+               dev_err(ds->dev, "Failed to read PTP clock: %d\n", rc);
                kfree_skb(skb);
                goto out;
        }
index b9b4edb..9b7f1af 100644 (file)
@@ -1249,8 +1249,12 @@ out_disable_adv_intr:
 
 static void __alx_stop(struct alx_priv *alx)
 {
-       alx_halt(alx);
        alx_free_irq(alx);
+
+       cancel_work_sync(&alx->link_check_wk);
+       cancel_work_sync(&alx->reset_wk);
+
+       alx_halt(alx);
        alx_free_rings(alx);
        alx_free_napis(alx);
 }
@@ -1855,9 +1859,6 @@ static void alx_remove(struct pci_dev *pdev)
        struct alx_priv *alx = pci_get_drvdata(pdev);
        struct alx_hw *hw = &alx->hw;
 
-       cancel_work_sync(&alx->link_check_wk);
-       cancel_work_sync(&alx->reset_wk);
-
        /* restore permanent mac address */
        alx_set_macaddr(hw, hw->perm_addr);
 
index c62589c..b93e05f 100644 (file)
@@ -10037,7 +10037,7 @@ static void bnxt_timer(struct timer_list *t)
        struct bnxt *bp = from_timer(bp, t, timer);
        struct net_device *dev = bp->dev;
 
-       if (!netif_running(dev))
+       if (!netif_running(dev) || !test_bit(BNXT_STATE_OPEN, &bp->state))
                return;
 
        if (atomic_read(&bp->intr_sem) != 0)
@@ -12133,19 +12133,9 @@ static int bnxt_resume(struct device *device)
                goto resume_exit;
        }
 
-       if (bnxt_hwrm_queue_qportcfg(bp)) {
-               rc = -ENODEV;
+       rc = bnxt_hwrm_func_qcaps(bp);
+       if (rc)
                goto resume_exit;
-       }
-
-       if (bp->hwrm_spec_code >= 0x10803) {
-               if (bnxt_alloc_ctx_mem(bp)) {
-                       rc = -ENODEV;
-                       goto resume_exit;
-               }
-       }
-       if (BNXT_NEW_RM(bp))
-               bnxt_hwrm_func_resc_qcaps(bp, false);
 
        if (bnxt_hwrm_func_drv_rgtr(bp, NULL, 0, false)) {
                rc = -ENODEV;
@@ -12161,6 +12151,8 @@ static int bnxt_resume(struct device *device)
 
 resume_exit:
        bnxt_ulp_start(bp, rc);
+       if (!rc)
+               bnxt_reenable_sriov(bp);
        rtnl_unlock();
        return rc;
 }
@@ -12204,6 +12196,9 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
                bnxt_close(netdev);
 
        pci_disable_device(pdev);
+       bnxt_free_ctx_mem(bp);
+       kfree(bp->ctx);
+       bp->ctx = NULL;
        rtnl_unlock();
 
        /* Request a slot slot reset. */
@@ -12237,12 +12232,16 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
                pci_set_master(pdev);
 
                err = bnxt_hwrm_func_reset(bp);
-               if (!err && netif_running(netdev))
-                       err = bnxt_open(netdev);
-
-               if (!err)
-                       result = PCI_ERS_RESULT_RECOVERED;
+               if (!err) {
+                       err = bnxt_hwrm_func_qcaps(bp);
+                       if (!err && netif_running(netdev))
+                               err = bnxt_open(netdev);
+               }
                bnxt_ulp_start(bp, err);
+               if (!err) {
+                       bnxt_reenable_sriov(bp);
+                       result = PCI_ERS_RESULT_RECOVERED;
+               }
        }
 
        if (result != PCI_ERS_RESULT_RECOVERED) {
index 5b9d7c6..6793307 100644 (file)
@@ -2565,15 +2565,14 @@ static int macb_open(struct net_device *dev)
        if (bp->ptp_info)
                bp->ptp_info->ptp_init(dev);
 
+       return 0;
+
 napi_exit:
        for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
                napi_disable(&queue->napi);
 pm_exit:
-       if (err) {
-               pm_runtime_put_sync(&bp->pdev->dev);
-               return err;
-       }
-       return 0;
+       pm_runtime_put_sync(&bp->pdev->dev);
+       return err;
 }
 
 static int macb_close(struct net_device *dev)
index 1b4d04e..2baf7b3 100644 (file)
@@ -842,12 +842,13 @@ static int ibmvnic_login(struct net_device *netdev)
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
        unsigned long timeout = msecs_to_jiffies(30000);
        int retry_count = 0;
+       int retries = 10;
        bool retry;
        int rc;
 
        do {
                retry = false;
-               if (retry_count > IBMVNIC_MAX_QUEUES) {
+               if (retry_count > retries) {
                        netdev_warn(netdev, "Login attempts exceeded\n");
                        return -1;
                }
@@ -862,11 +863,23 @@ static int ibmvnic_login(struct net_device *netdev)
 
                if (!wait_for_completion_timeout(&adapter->init_done,
                                                 timeout)) {
-                       netdev_warn(netdev, "Login timed out\n");
-                       return -1;
+                       netdev_warn(netdev, "Login timed out, retrying...\n");
+                       retry = true;
+                       adapter->init_done_rc = 0;
+                       retry_count++;
+                       continue;
                }
 
-               if (adapter->init_done_rc == PARTIALSUCCESS) {
+               if (adapter->init_done_rc == ABORTED) {
+                       netdev_warn(netdev, "Login aborted, retrying...\n");
+                       retry = true;
+                       adapter->init_done_rc = 0;
+                       retry_count++;
+                       /* FW or device may be busy, so
+                        * wait a bit before retrying login
+                        */
+                       msleep(500);
+               } else if (adapter->init_done_rc == PARTIALSUCCESS) {
                        retry_count++;
                        release_sub_crqs(adapter, 1);
 
index d9fa460..4b2de08 100644 (file)
@@ -151,10 +151,8 @@ static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
                                  __be16 proto, u16 vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-#ifdef CONFIG_PM
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
-static int e1000_resume(struct pci_dev *pdev);
-#endif
+static int __maybe_unused e1000_suspend(struct device *dev);
+static int __maybe_unused e1000_resume(struct device *dev);
 static void e1000_shutdown(struct pci_dev *pdev);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -179,16 +177,16 @@ static const struct pci_error_handlers e1000_err_handler = {
        .resume = e1000_io_resume,
 };
 
+static SIMPLE_DEV_PM_OPS(e1000_pm_ops, e1000_suspend, e1000_resume);
+
 static struct pci_driver e1000_driver = {
        .name     = e1000_driver_name,
        .id_table = e1000_pci_tbl,
        .probe    = e1000_probe,
        .remove   = e1000_remove,
-#ifdef CONFIG_PM
-       /* Power Management Hooks */
-       .suspend  = e1000_suspend,
-       .resume   = e1000_resume,
-#endif
+       .driver = {
+               .pm = &e1000_pm_ops,
+       },
        .shutdown = e1000_shutdown,
        .err_handler = &e1000_err_handler
 };
@@ -5060,9 +5058,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
        struct e1000_hw *hw = &adapter->hw;
        u32 ctrl, ctrl_ext, rctl, status;
        u32 wufc = adapter->wol;
-#ifdef CONFIG_PM
-       int retval = 0;
-#endif
 
        netif_device_detach(netdev);
 
@@ -5076,12 +5071,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
                e1000_down(adapter);
        }
 
-#ifdef CONFIG_PM
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-#endif
-
        status = er32(STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
@@ -5142,37 +5131,26 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __maybe_unused e1000_suspend(struct device *dev)
 {
        int retval;
+       struct pci_dev *pdev = to_pci_dev(dev);
        bool wake;
 
        retval = __e1000_shutdown(pdev, &wake);
-       if (retval)
-               return retval;
-
-       if (wake) {
-               pci_prepare_to_sleep(pdev);
-       } else {
-               pci_wake_from_d3(pdev, false);
-               pci_set_power_state(pdev, PCI_D3hot);
-       }
+       device_set_wakeup_enable(dev, wake);
 
-       return 0;
+       return retval;
 }
 
-static int e1000_resume(struct pci_dev *pdev)
+static int __maybe_unused e1000_resume(struct device *dev)
 {
+       struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
        u32 err;
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_save_state(pdev);
-
        if (adapter->need_ioport)
                err = pci_enable_device(pdev);
        else
@@ -5209,7 +5187,6 @@ static int e1000_resume(struct pci_dev *pdev)
 
        return 0;
 }
-#endif
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
index a279f4f..6f6479c 100644 (file)
@@ -6349,7 +6349,6 @@ fl_out:
        pm_runtime_put_sync(netdev->dev.parent);
 }
 
-#ifdef CONFIG_PM_SLEEP
 /* S0ix implementation */
 static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
 {
@@ -6571,7 +6570,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
        mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS;
        ew32(CTRL_EXT, mac_data);
 }
-#endif /* CONFIG_PM_SLEEP */
 
 static int e1000e_pm_freeze(struct device *dev)
 {
@@ -6611,11 +6609,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       u32 ctrl, ctrl_ext, rctl, status;
-       /* Runtime suspend should only enable wakeup for link changes */
-       u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
+       u32 ctrl, ctrl_ext, rctl, status, wufc;
        int retval = 0;
 
+       /* Runtime suspend should only enable wakeup for link changes */
+       if (runtime)
+               wufc = E1000_WUFC_LNKC;
+       else if (device_may_wakeup(&pdev->dev))
+               wufc = adapter->wol;
+       else
+               wufc = 0;
+
        status = er32(STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
@@ -6672,7 +6676,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
        if (adapter->hw.phy.type == e1000_phy_igp_3) {
                e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
        } else if (hw->mac.type >= e1000_pch_lpt) {
-               if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC)))
+               if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC)))
                        /* ULP does not support wake from unicast, multicast
                         * or broadcast.
                         */
@@ -6869,7 +6873,6 @@ err_irq:
        return rc;
 }
 
-#ifdef CONFIG_PM
 static int __e1000_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -6935,8 +6938,7 @@ static int __e1000_resume(struct pci_dev *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int e1000e_pm_suspend(struct device *dev)
+static __maybe_unused int e1000e_pm_suspend(struct device *dev)
 {
        struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -6960,7 +6962,7 @@ static int e1000e_pm_suspend(struct device *dev)
        return rc;
 }
 
-static int e1000e_pm_resume(struct device *dev)
+static __maybe_unused int e1000e_pm_resume(struct device *dev)
 {
        struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -6979,9 +6981,8 @@ static int e1000e_pm_resume(struct device *dev)
 
        return e1000e_pm_thaw(dev);
 }
-#endif /* CONFIG_PM_SLEEP */
 
-static int e1000e_pm_runtime_idle(struct device *dev)
+static __maybe_unused int e1000e_pm_runtime_idle(struct device *dev)
 {
        struct net_device *netdev = dev_get_drvdata(dev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -6997,7 +6998,7 @@ static int e1000e_pm_runtime_idle(struct device *dev)
        return -EBUSY;
 }
 
-static int e1000e_pm_runtime_resume(struct device *dev)
+static __maybe_unused int e1000e_pm_runtime_resume(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -7014,7 +7015,7 @@ static int e1000e_pm_runtime_resume(struct device *dev)
        return rc;
 }
 
-static int e1000e_pm_runtime_suspend(struct device *dev)
+static __maybe_unused int e1000e_pm_runtime_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -7039,7 +7040,6 @@ static int e1000e_pm_runtime_suspend(struct device *dev)
 
        return 0;
 }
-#endif /* CONFIG_PM */
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
index 2b5dad2..24f4d8e 100644 (file)
@@ -1544,7 +1544,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port)
        for (q = 0; q < port->ntxqs; q++)
                for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++)
                        *pstats++ += mvpp2_read_index(port->priv,
-                                                     MVPP22_CTRS_TX_CTR(port->id, i),
+                                                     MVPP22_CTRS_TX_CTR(port->id, q),
                                                      mvpp2_ethtool_txq_regs[i].offset);
 
        /* Rxqs are numbered from 0 from the user standpoint, but not from the
@@ -1553,7 +1553,7 @@ static void mvpp2_read_stats(struct mvpp2_port *port)
        for (q = 0; q < port->nrxqs; q++)
                for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++)
                        *pstats++ += mvpp2_read_index(port->priv,
-                                                     port->first_rxq + i,
+                                                     port->first_rxq + q,
                                                      mvpp2_ethtool_rxq_regs[i].offset);
 }
 
@@ -5983,8 +5983,8 @@ static int mvpp2_remove(struct platform_device *pdev)
 {
        struct mvpp2 *priv = platform_get_drvdata(pdev);
        struct fwnode_handle *fwnode = pdev->dev.fwnode;
+       int i = 0, poolnum = MVPP2_BM_POOLS_NUM;
        struct fwnode_handle *port_fwnode;
-       int i = 0;
 
        mvpp2_dbgfs_cleanup(priv);
 
@@ -5998,7 +5998,10 @@ static int mvpp2_remove(struct platform_device *pdev)
 
        destroy_workqueue(priv->stats_queue);
 
-       for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
+       if (priv->percpu_pools)
+               poolnum = mvpp2_get_nrxqs(priv) * 2;
+
+       for (i = 0; i < poolnum; i++) {
                struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i];
 
                mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool);
index f1ace4f..3e765bd 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/regmap.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
-#include <linux/workqueue.h>
 
 #define MTK_STAR_DRVNAME                       "mtk_star_emac"
 
@@ -262,7 +261,6 @@ struct mtk_star_priv {
        spinlock_t lock;
 
        struct rtnl_link_stats64 stats;
-       struct work_struct stats_work;
 };
 
 static struct device *mtk_star_get_dev(struct mtk_star_priv *priv)
@@ -432,42 +430,6 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv)
        regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0);
 }
 
-static void mtk_star_intr_enable_tx(struct mtk_star_priv *priv)
-{
-       regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                         MTK_STAR_BIT_INT_STS_TNTC);
-}
-
-static void mtk_star_intr_enable_rx(struct mtk_star_priv *priv)
-{
-       regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                         MTK_STAR_BIT_INT_STS_FNRC);
-}
-
-static void mtk_star_intr_enable_stats(struct mtk_star_priv *priv)
-{
-       regmap_clear_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                         MTK_STAR_REG_INT_STS_MIB_CNT_TH);
-}
-
-static void mtk_star_intr_disable_tx(struct mtk_star_priv *priv)
-{
-       regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                       MTK_STAR_BIT_INT_STS_TNTC);
-}
-
-static void mtk_star_intr_disable_rx(struct mtk_star_priv *priv)
-{
-       regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                       MTK_STAR_BIT_INT_STS_FNRC);
-}
-
-static void mtk_star_intr_disable_stats(struct mtk_star_priv *priv)
-{
-       regmap_set_bits(priv->regs, MTK_STAR_REG_INT_MASK,
-                       MTK_STAR_REG_INT_STS_MIB_CNT_TH);
-}
-
 static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv)
 {
        unsigned int val;
@@ -663,20 +625,6 @@ static void mtk_star_update_stats(struct mtk_star_priv *priv)
        stats->rx_errors += stats->rx_fifo_errors;
 }
 
-/* This runs in process context and parallel TX and RX paths executing in
- * napi context may result in losing some stats data but this should happen
- * seldom enough to be acceptable.
- */
-static void mtk_star_update_stats_work(struct work_struct *work)
-{
-       struct mtk_star_priv *priv = container_of(work, struct mtk_star_priv,
-                                                stats_work);
-
-       mtk_star_update_stats(priv);
-       mtk_star_reset_counters(priv);
-       mtk_star_intr_enable_stats(priv);
-}
-
 static struct sk_buff *mtk_star_alloc_skb(struct net_device *ndev)
 {
        uintptr_t tail, offset;
@@ -767,42 +715,25 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv)
        mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx);
 }
 
-/* All processing for TX and RX happens in the napi poll callback. */
+/* All processing for TX and RX happens in the napi poll callback.
+ *
+ * FIXME: The interrupt handling should be more fine-grained with each
+ * interrupt enabled/disabled independently when needed. Unfortunatly this
+ * turned out to impact the driver's stability and until we have something
+ * working properly, we're disabling all interrupts during TX & RX processing
+ * or when resetting the counter registers.
+ */
 static irqreturn_t mtk_star_handle_irq(int irq, void *data)
 {
        struct mtk_star_priv *priv;
        struct net_device *ndev;
-       bool need_napi = false;
-       unsigned int status;
 
        ndev = data;
        priv = netdev_priv(ndev);
 
        if (netif_running(ndev)) {
-               status = mtk_star_intr_read(priv);
-
-               if (status & MTK_STAR_BIT_INT_STS_TNTC) {
-                       mtk_star_intr_disable_tx(priv);
-                       need_napi = true;
-               }
-
-               if (status & MTK_STAR_BIT_INT_STS_FNRC) {
-                       mtk_star_intr_disable_rx(priv);
-                       need_napi = true;
-               }
-
-               if (need_napi)
-                       napi_schedule(&priv->napi);
-
-               /* One of the counters reached 0x8000000 - update stats and
-                * reset all counters.
-                */
-               if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
-                       mtk_star_intr_disable_stats(priv);
-                       schedule_work(&priv->stats_work);
-               }
-
-               mtk_star_intr_ack_all(priv);
+               mtk_star_intr_disable(priv);
+               napi_schedule(&priv->napi);
        }
 
        return IRQ_HANDLED;
@@ -1169,8 +1100,6 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
        if (wake && netif_queue_stopped(ndev))
                netif_wake_queue(ndev);
 
-       mtk_star_intr_enable_tx(priv);
-
        spin_unlock(&priv->lock);
 }
 
@@ -1332,20 +1261,32 @@ static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
 static int mtk_star_poll(struct napi_struct *napi, int budget)
 {
        struct mtk_star_priv *priv;
+       unsigned int status;
        int received = 0;
 
        priv = container_of(napi, struct mtk_star_priv, napi);
 
-       /* Clean-up all TX descriptors. */
-       mtk_star_tx_complete_all(priv);
-       /* Receive up to $budget packets. */
-       received = mtk_star_process_rx(priv, budget);
+       status = mtk_star_intr_read(priv);
+       mtk_star_intr_ack_all(priv);
 
-       if (received < budget) {
-               napi_complete_done(napi, received);
-               mtk_star_intr_enable_rx(priv);
+       if (status & MTK_STAR_BIT_INT_STS_TNTC)
+               /* Clean-up all TX descriptors. */
+               mtk_star_tx_complete_all(priv);
+
+       if (status & MTK_STAR_BIT_INT_STS_FNRC)
+               /* Receive up to $budget packets. */
+               received = mtk_star_process_rx(priv, budget);
+
+       if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
+               mtk_star_update_stats(priv);
+               mtk_star_reset_counters(priv);
        }
 
+       if (received < budget)
+               napi_complete_done(napi, received);
+
+       mtk_star_intr_enable(priv);
+
        return received;
 }
 
@@ -1532,7 +1473,6 @@ static int mtk_star_probe(struct platform_device *pdev)
        ndev->max_mtu = MTK_STAR_MAX_FRAME_SIZE;
 
        spin_lock_init(&priv->lock);
-       INIT_WORK(&priv->stats_work, mtk_star_update_stats_work);
 
        base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
index 5ffa32b..55af877 100644 (file)
@@ -978,8 +978,10 @@ int __mlxsw_sp_port_headroom_set(struct mlxsw_sp_port *mlxsw_sp_port, int mtu,
 
                lossy = !(pfc || pause_en);
                thres_cells = mlxsw_sp_pg_buf_threshold_get(mlxsw_sp, mtu);
+               mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &thres_cells);
                delay_cells = mlxsw_sp_pg_buf_delay_get(mlxsw_sp, mtu, delay,
                                                        pfc, pause_en);
+               mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &delay_cells);
                total_cells = thres_cells + delay_cells;
 
                taken_headroom_cells += total_cells;
index 6f96ca5..6e87457 100644 (file)
@@ -374,6 +374,19 @@ mlxsw_sp_port_vlan_find_by_vid(const struct mlxsw_sp_port *mlxsw_sp_port,
        return NULL;
 }
 
+static inline void
+mlxsw_sp_port_headroom_8x_adjust(const struct mlxsw_sp_port *mlxsw_sp_port,
+                                u16 *p_size)
+{
+       /* Ports with eight lanes use two headroom buffers between which the
+        * configured headroom size is split. Therefore, multiply the calculated
+        * headroom size by two.
+        */
+       if (mlxsw_sp_port->mapping.width != 8)
+               return;
+       *p_size *= 2;
+}
+
 enum mlxsw_sp_flood_type {
        MLXSW_SP_FLOOD_TYPE_UC,
        MLXSW_SP_FLOOD_TYPE_BC,
index 21bfb2f..f25a8b0 100644 (file)
@@ -312,6 +312,7 @@ static int mlxsw_sp_port_pb_init(struct mlxsw_sp_port *mlxsw_sp_port)
 
                if (i == MLXSW_SP_PB_UNUSED)
                        continue;
+               mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, &size);
                mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl, i, size);
        }
        mlxsw_reg_pbmc_lossy_buffer_pack(pbmc_pl,
index 304eb8c..f843545 100644 (file)
@@ -782,6 +782,7 @@ mlxsw_sp_span_port_buffer_update(struct mlxsw_sp_port *mlxsw_sp_port, u16 mtu)
                speed = 0;
 
        buffsize = mlxsw_sp_span_buffsize_get(mlxsw_sp, speed, mtu);
+       mlxsw_sp_port_headroom_8x_adjust(mlxsw_sp_port, (u16 *) &buffsize);
        mlxsw_reg_sbib_pack(sbib_pl, mlxsw_sp_port->local_port, buffsize);
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sbib), sbib_pl);
 }
index c5c5c68..f1711ac 100644 (file)
@@ -3091,6 +3091,8 @@ static const struct pci_device_id lan743x_pcidev_tbl[] = {
        { 0, }
 };
 
+MODULE_DEVICE_TABLE(pci, lan743x_pcidev_tbl);
+
 static struct pci_driver lan743x_pcidev_driver = {
        .name     = DRIVER_NAME,
        .id_table = lan743x_pcidev_tbl,
index 8d7b9bb..1003763 100644 (file)
@@ -269,7 +269,7 @@ static ssize_t qlcnic_sysfs_read_crb(struct file *filp, struct kobject *kobj,
                                     struct bin_attribute *attr, char *buf,
                                     loff_t offset, size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        int ret;
 
@@ -286,7 +286,7 @@ static ssize_t qlcnic_sysfs_write_crb(struct file *filp, struct kobject *kobj,
                                      struct bin_attribute *attr, char *buf,
                                      loff_t offset, size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        int ret;
 
@@ -315,7 +315,7 @@ static ssize_t qlcnic_sysfs_read_mem(struct file *filp, struct kobject *kobj,
                                     struct bin_attribute *attr, char *buf,
                                     loff_t offset, size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        u64 data;
        int ret;
@@ -337,7 +337,7 @@ static ssize_t qlcnic_sysfs_write_mem(struct file *filp, struct kobject *kobj,
                                      struct bin_attribute *attr, char *buf,
                                      loff_t offset, size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        u64 data;
        int ret;
@@ -402,7 +402,7 @@ static ssize_t qlcnic_sysfs_write_pm_config(struct file *filp,
                                            char *buf, loff_t offset,
                                            size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_pm_func_cfg *pm_cfg;
        u32 id, action, pci_func;
@@ -452,7 +452,7 @@ static ssize_t qlcnic_sysfs_read_pm_config(struct file *filp,
                                           char *buf, loff_t offset,
                                           size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_pm_func_cfg *pm_cfg;
        u8 pci_func;
@@ -545,7 +545,7 @@ static ssize_t qlcnic_sysfs_write_esw_config(struct file *file,
                                             char *buf, loff_t offset,
                                             size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_esw_func_cfg *esw_cfg;
        struct qlcnic_npar_info *npar;
@@ -629,7 +629,7 @@ static ssize_t qlcnic_sysfs_read_esw_config(struct file *file,
                                            char *buf, loff_t offset,
                                            size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_esw_func_cfg *esw_cfg;
        u8 pci_func;
@@ -681,7 +681,7 @@ static ssize_t qlcnic_sysfs_write_npar_config(struct file *file,
                                              char *buf, loff_t offset,
                                              size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_info nic_info;
        struct qlcnic_npar_func_cfg *np_cfg;
@@ -728,7 +728,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file,
                                             char *buf, loff_t offset,
                                             size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_npar_func_cfg *np_cfg;
        struct qlcnic_info nic_info;
@@ -775,7 +775,7 @@ static ssize_t qlcnic_sysfs_get_port_stats(struct file *file,
                                           char *buf, loff_t offset,
                                           size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_esw_statistics port_stats;
        int ret;
@@ -810,7 +810,7 @@ static ssize_t qlcnic_sysfs_get_esw_stats(struct file *file,
                                          char *buf, loff_t offset,
                                          size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_esw_statistics esw_stats;
        int ret;
@@ -845,7 +845,7 @@ static ssize_t qlcnic_sysfs_clear_esw_stats(struct file *file,
                                            char *buf, loff_t offset,
                                            size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        int ret;
 
@@ -875,7 +875,7 @@ static ssize_t qlcnic_sysfs_clear_port_stats(struct file *file,
                                             size_t size)
 {
 
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        int ret;
 
@@ -904,7 +904,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file,
                                            char *buf, loff_t offset,
                                            size_t size)
 {
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
        struct qlcnic_pci_func_cfg *pci_cfg;
        struct qlcnic_pci_info *pci_info;
@@ -946,7 +946,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_read_handler(struct file *filp,
 {
        unsigned char *p_read_buf;
        int  ret, count;
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 
        if (!size)
@@ -1124,7 +1124,7 @@ static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
        int  ret;
        static int flash_mode;
        unsigned long data;
-       struct device *dev = container_of(kobj, struct device, kobj);
+       struct device *dev = kobj_to_dev(kobj);
        struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
 
        ret = kstrtoul(buf, 16, &data);
index 7585cd2..fc99e71 100644 (file)
@@ -647,10 +647,10 @@ static int rocker_dma_rings_init(struct rocker *rocker)
 err_dma_event_ring_bufs_alloc:
        rocker_dma_ring_destroy(rocker, &rocker->event_ring);
 err_dma_event_ring_create:
+       rocker_dma_cmd_ring_waits_free(rocker);
+err_dma_cmd_ring_waits_alloc:
        rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring,
                                  PCI_DMA_BIDIRECTIONAL);
-err_dma_cmd_ring_waits_alloc:
-       rocker_dma_cmd_ring_waits_free(rocker);
 err_dma_cmd_ring_bufs_alloc:
        rocker_dma_ring_destroy(rocker, &rocker->cmd_ring);
        return err;
index fbaf3c9..f34c790 100644 (file)
 #define XAE_RAF_TXVSTRPMODE_MASK       0x00000180 /* Tx VLAN STRIP mode */
 #define XAE_RAF_RXVSTRPMODE_MASK       0x00000600 /* Rx VLAN STRIP mode */
 #define XAE_RAF_NEWFNCENBL_MASK                0x00000800 /* New function mode */
-/* Exteneded Multicast Filtering mode */
+/* Extended Multicast Filtering mode */
 #define XAE_RAF_EMULTIFLTRENBL_MASK    0x00001000
 #define XAE_RAF_STATSRST_MASK          0x00002000 /* Stats. Counter Reset */
 #define XAE_RAF_RXBADFRMEN_MASK                0x00004000 /* Recv Bad Frame Enable */
index ccbb5b4..4502f9c 100644 (file)
@@ -679,18 +679,8 @@ static umode_t region_visible(struct kobject *kobj, struct attribute *a, int n)
                return a->mode;
        }
 
-       if (a == &dev_attr_align.attr) {
-               int i;
-
-               for (i = 0; i < nd_region->ndr_mappings; i++) {
-                       struct nd_mapping *nd_mapping = &nd_region->mapping[i];
-                       struct nvdimm *nvdimm = nd_mapping->nvdimm;
-
-                       if (test_bit(NDD_LABELING, &nvdimm->flags))
-                               return a->mode;
-               }
-               return 0;
-       }
+       if (a == &dev_attr_align.attr)
+               return a->mode;
 
        if (a != &dev_attr_set_cookie.attr
                        && a != &dev_attr_available_size.attr)
index e1d097e..31478c0 100644 (file)
@@ -33,7 +33,7 @@ void flush_cpu_work(void);
 struct op_sample {
        unsigned long eip;
        unsigned long event;
-       unsigned long data[0];
+       unsigned long data[];
 };
 
 struct op_entry;
index 2c1a7d7..77fb23b 100644 (file)
@@ -43,7 +43,7 @@ struct samsung_usb2_phy_driver {
        struct regmap *reg_pmu;
        struct regmap *reg_sys;
        spinlock_t lock;
-       struct samsung_usb2_phy_instance instances[0];
+       struct samsung_usb2_phy_instance instances[];
 };
 
 struct samsung_usb2_common_phy {
index cb7e0f0..1f81569 100644 (file)
@@ -824,13 +824,12 @@ int imx_pinctrl_probe(struct platform_device *pdev,
                                return -EINVAL;
                        }
 
-                       ipctl->input_sel_base = devm_of_iomap(&pdev->dev, np,
-                                                             0, NULL);
+                       ipctl->input_sel_base = of_iomap(np, 0);
                        of_node_put(np);
-                       if (IS_ERR(ipctl->input_sel_base)) {
+                       if (!ipctl->input_sel_base) {
                                dev_err(&pdev->dev,
                                        "iomuxc input select base address not found\n");
-                               return PTR_ERR(ipctl->input_sel_base);
+                               return -ENOMEM;
                        }
                }
        }
index e06fb88..1f47a66 100644 (file)
@@ -126,10 +126,7 @@ static int mcp23s08_spi_regmap_init(struct mcp23s08 *mcp, struct device *dev,
        copy->name = name;
 
        mcp->regmap = devm_regmap_init(dev, &mcp23sxx_spi_regmap, mcp, copy);
-       if (IS_ERR(mcp->regmap))
-               return PTR_ERR(mcp->regmap);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(mcp->regmap);
 }
 
 static int mcp23s08_probe(struct spi_device *spi)
index 1e0614d..f3a8a46 100644 (file)
@@ -958,7 +958,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
 }
 
 /**
- * smux_parse_one_pinctrl_entry() - parses a device tree mux entry
+ * pcs_parse_one_pinctrl_entry() - parses a device tree mux entry
  * @pctldev: pin controller device
  * @pcs: pinctrl driver instance
  * @np: device node of the mux entry
index 38c33a7..ec50a3b 100644 (file)
@@ -367,7 +367,8 @@ static const char * const wci20_groups[] = {
 
 static const char * const qpic_pad_groups[] = {
        "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio9", "gpio10",
-       "gpio11", "gpio17",
+       "gpio11", "gpio17", "gpio15", "gpio12", "gpio13", "gpio14", "gpio5",
+       "gpio6", "gpio7", "gpio8",
 };
 
 static const char * const burn0_groups[] = {
index fe0be8a..092a48e 100644 (file)
@@ -170,6 +170,7 @@ struct pmic_gpio_state {
        struct regmap   *map;
        struct pinctrl_dev *ctrl;
        struct gpio_chip chip;
+       struct irq_chip irq;
 };
 
 static const struct pinconf_generic_params pmic_gpio_bindings[] = {
@@ -917,16 +918,6 @@ static int pmic_gpio_populate(struct pmic_gpio_state *state,
        return 0;
 }
 
-static struct irq_chip pmic_gpio_irq_chip = {
-       .name = "spmi-gpio",
-       .irq_ack = irq_chip_ack_parent,
-       .irq_mask = irq_chip_mask_parent,
-       .irq_unmask = irq_chip_unmask_parent,
-       .irq_set_type = irq_chip_set_type_parent,
-       .irq_set_wake = irq_chip_set_wake_parent,
-       .flags = IRQCHIP_MASK_ON_SUSPEND,
-};
-
 static int pmic_gpio_domain_translate(struct irq_domain *domain,
                                      struct irq_fwspec *fwspec,
                                      unsigned long *hwirq,
@@ -1053,8 +1044,16 @@ static int pmic_gpio_probe(struct platform_device *pdev)
        if (!parent_domain)
                return -ENXIO;
 
+       state->irq.name = "spmi-gpio",
+       state->irq.irq_ack = irq_chip_ack_parent,
+       state->irq.irq_mask = irq_chip_mask_parent,
+       state->irq.irq_unmask = irq_chip_unmask_parent,
+       state->irq.irq_set_type = irq_chip_set_type_parent,
+       state->irq.irq_set_wake = irq_chip_set_wake_parent,
+       state->irq.flags = IRQCHIP_MASK_ON_SUSPEND,
+
        girq = &state->chip.irq;
-       girq->chip = &pmic_gpio_irq_chip;
+       girq->chip = &state->irq;
        girq->default_type = IRQ_TYPE_NONE;
        girq->handler = handle_level_irq;
        girq->fwnode = of_node_to_fwnode(state->dev->of_node);
index 21661f6..195cfe5 100644 (file)
@@ -731,8 +731,8 @@ static int tegra_pinctrl_resume(struct device *dev)
 }
 
 const struct dev_pm_ops tegra_pinctrl_pm = {
-       .suspend = &tegra_pinctrl_suspend,
-       .resume = &tegra_pinctrl_resume
+       .suspend_noirq = &tegra_pinctrl_suspend,
+       .resume_noirq = &tegra_pinctrl_resume
 };
 
 static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
index 0e90c5d..eb8ed28 100644 (file)
@@ -39,7 +39,7 @@ struct rio_id_table {
        u16 start;      /* logical minimal id */
        u32 max;        /* max number of IDs in table */
        spinlock_t lock;
-       unsigned long table[0];
+       unsigned long table[];
 };
 
 static int next_destid = 0;
index eb13c47..bb1c840 100644 (file)
@@ -182,10 +182,9 @@ enum qdio_irq_poll_states {
 };
 
 struct qdio_input_q {
-       /* first ACK'ed buffer */
-       int ack_start;
-       /* how many SBALs are acknowledged */
-       int ack_count;
+       /* Batch of SBALs that we processed while polling the queue: */
+       unsigned int batch_start;
+       unsigned int batch_count;
        /* last time of noticing incoming data */
        u64 timestamp;
 };
index 286b044..da95c92 100644 (file)
@@ -110,8 +110,8 @@ static int qstat_show(struct seq_file *m, void *v)
        seq_printf(m, "nr_used: %d  ftc: %d\n",
                   atomic_read(&q->nr_buf_used), q->first_to_check);
        if (q->is_input_q) {
-               seq_printf(m, "ack start: %d  ack count: %d\n",
-                          q->u.in.ack_start, q->u.in.ack_count);
+               seq_printf(m, "batch start: %u  batch count: %u\n",
+                          q->u.in.batch_start, q->u.in.batch_count);
                seq_printf(m, "DSCI: %x   IRQs disabled: %u\n",
                           *(u8 *)q->irq_ptr->dsci,
                           test_bit(QDIO_IRQ_DISABLED,
index 610c05f..0c919a1 100644 (file)
@@ -254,10 +254,17 @@ static inline int set_buf_states(struct qdio_q *q, int bufnr,
        if (is_qebsm(q))
                return qdio_do_sqbs(q, state, bufnr, count);
 
+       /* Ensure that all preceding changes to the SBALs are visible: */
+       mb();
+
        for (i = 0; i < count; i++) {
-               xchg(&q->slsb.val[bufnr], state);
+               WRITE_ONCE(q->slsb.val[bufnr], state);
                bufnr = next_buf(bufnr);
        }
+
+       /* Make our SLSB changes visible: */
+       mb();
+
        return count;
 }
 
@@ -393,15 +400,15 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
 
 static inline void qdio_stop_polling(struct qdio_q *q)
 {
-       if (!q->u.in.ack_count)
+       if (!q->u.in.batch_count)
                return;
 
        qperf_inc(q, stop_polling);
 
        /* show the card that we are not polling anymore */
-       set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
-                      q->u.in.ack_count);
-       q->u.in.ack_count = 0;
+       set_buf_states(q, q->u.in.batch_start, SLSB_P_INPUT_NOT_INIT,
+                      q->u.in.batch_count);
+       q->u.in.batch_count = 0;
 }
 
 static inline void account_sbals(struct qdio_q *q, unsigned int count)
@@ -441,42 +448,13 @@ static void process_buffer_error(struct qdio_q *q, unsigned int start,
 static inline void inbound_handle_work(struct qdio_q *q, unsigned int start,
                                       int count, bool auto_ack)
 {
-       int new;
-
-       if (auto_ack) {
-               if (!q->u.in.ack_count) {
-                       q->u.in.ack_count = count;
-                       q->u.in.ack_start = start;
-                       return;
-               }
-
-               /* delete the previous ACK's */
-               set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
-                              q->u.in.ack_count);
-               q->u.in.ack_count = count;
-               q->u.in.ack_start = start;
-               return;
-       }
-
-       /*
-        * ACK the newest buffer. The ACK will be removed in qdio_stop_polling
-        * or by the next inbound run.
-        */
-       new = add_buf(start, count - 1);
-       set_buf_state(q, new, SLSB_P_INPUT_ACK);
-
-       /* delete the previous ACKs */
-       if (q->u.in.ack_count)
-               set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
-                              q->u.in.ack_count);
+       /* ACK the newest SBAL: */
+       if (!auto_ack)
+               set_buf_state(q, add_buf(start, count - 1), SLSB_P_INPUT_ACK);
 
-       q->u.in.ack_count = 1;
-       q->u.in.ack_start = new;
-       count--;
-       if (!count)
-               return;
-       /* need to change ALL buffers to get more interrupts */
-       set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
+       if (!q->u.in.batch_count)
+               q->u.in.batch_start = start;
+       q->u.in.batch_count += count;
 }
 
 static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
@@ -525,15 +503,18 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
                        account_sbals_error(q, count);
                return count;
        case SLSB_CU_INPUT_EMPTY:
-       case SLSB_P_INPUT_NOT_INIT:
-       case SLSB_P_INPUT_ACK:
                if (q->irq_ptr->perf_stat_enabled)
                        q->q_stats.nr_sbal_nop++;
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop:%1d %#02x",
                              q->nr, start);
                return 0;
+       case SLSB_P_INPUT_NOT_INIT:
+       case SLSB_P_INPUT_ACK:
+               /* We should never see this state, throw a WARN: */
        default:
-               WARN_ON_ONCE(1);
+               dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1,
+                             "found state %#x at index %u on queue %u\n",
+                             state, start, q->nr);
                return 0;
        }
 }
@@ -738,11 +719,14 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start)
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d",
                              q->nr);
                return 0;
-       case SLSB_P_OUTPUT_NOT_INIT:
        case SLSB_P_OUTPUT_HALTED:
                return 0;
+       case SLSB_P_OUTPUT_NOT_INIT:
+               /* We should never see this state, throw a WARN: */
        default:
-               WARN_ON_ONCE(1);
+               dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1,
+                             "found state %#x at index %u on queue %u\n",
+                             state, start, q->nr);
                return 0;
        }
 }
@@ -938,10 +922,10 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
        }
 }
 
-static void qdio_handle_activate_check(struct ccw_device *cdev,
-                               unsigned long intparm, int cstat, int dstat)
+static void qdio_handle_activate_check(struct qdio_irq *irq_ptr,
+                                      unsigned long intparm, int cstat,
+                                      int dstat)
 {
-       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
        struct qdio_q *q;
 
        DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
@@ -968,11 +952,9 @@ no_handler:
        lgr_info_log();
 }
 
-static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
+static void qdio_establish_handle_irq(struct qdio_irq *irq_ptr, int cstat,
                                      int dstat)
 {
-       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
-
        DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
 
        if (cstat)
@@ -1019,7 +1001,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
 
        switch (irq_ptr->state) {
        case QDIO_IRQ_STATE_INACTIVE:
-               qdio_establish_handle_irq(cdev, cstat, dstat);
+               qdio_establish_handle_irq(irq_ptr, cstat, dstat);
                break;
        case QDIO_IRQ_STATE_CLEANUP:
                qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
@@ -1031,7 +1013,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
                        return;
                }
                if (cstat || dstat)
-                       qdio_handle_activate_check(cdev, intparm, cstat,
+                       qdio_handle_activate_check(irq_ptr, intparm, cstat,
                                                   dstat);
                break;
        case QDIO_IRQ_STATE_STOPPED:
@@ -1446,12 +1428,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
 
        qperf_inc(q, inbound_call);
 
-       /* If any ACKed SBALs are returned to HW, adjust ACK tracking: */
-       overlap = min(count - sub_buf(q->u.in.ack_start, bufnr),
-                     q->u.in.ack_count);
+       /* If any processed SBALs are returned to HW, adjust our tracking: */
+       overlap = min_t(int, count - sub_buf(q->u.in.batch_start, bufnr),
+                            q->u.in.batch_count);
        if (overlap > 0) {
-               q->u.in.ack_start = add_buf(q->u.in.ack_start, overlap);
-               q->u.in.ack_count -= overlap;
+               q->u.in.batch_start = add_buf(q->u.in.batch_start, overlap);
+               q->u.in.batch_count -= overlap;
        }
 
        count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
@@ -1535,12 +1517,11 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
 int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
            int q_nr, unsigned int bufnr, unsigned int count)
 {
-       struct qdio_irq *irq_ptr;
+       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
 
        if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
                return -EINVAL;
 
-       irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
 
index 004ce02..3c3d403 100644 (file)
@@ -195,11 +195,10 @@ static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
        size_t len = sizeof(struct ep11_cprb) + payload_len;
        struct ep11_cprb *cprb;
 
-       cprb = kmalloc(len, GFP_KERNEL);
+       cprb = kzalloc(len, GFP_KERNEL);
        if (!cprb)
                return NULL;
 
-       memset(cprb, 0, len);
        cprb->cprb_len = sizeof(struct ep11_cprb);
        cprb->cprb_ver_id = 0x04;
        memcpy(cprb->func_id, "T4", 2);
index 957889a..5730572 100644 (file)
@@ -1372,27 +1372,6 @@ static struct ccw_device_id virtio_ids[] = {
        {},
 };
 
-#ifdef CONFIG_PM_SLEEP
-static int virtio_ccw_freeze(struct ccw_device *cdev)
-{
-       struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
-
-       return virtio_device_freeze(&vcdev->vdev);
-}
-
-static int virtio_ccw_restore(struct ccw_device *cdev)
-{
-       struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
-       int ret;
-
-       ret = virtio_ccw_set_transport_rev(vcdev);
-       if (ret)
-               return ret;
-
-       return virtio_device_restore(&vcdev->vdev);
-}
-#endif
-
 static struct ccw_driver virtio_ccw_driver = {
        .driver = {
                .owner = THIS_MODULE,
@@ -1405,11 +1384,6 @@ static struct ccw_driver virtio_ccw_driver = {
        .set_online = virtio_ccw_online,
        .notify = virtio_ccw_cio_notify,
        .int_class = IRQIO_VIR,
-#ifdef CONFIG_PM_SLEEP
-       .freeze = virtio_ccw_freeze,
-       .thaw = virtio_ccw_restore,
-       .restore = virtio_ccw_restore,
-#endif
 };
 
 static int __init pure_hex(char **cp, unsigned int *val, int min_digit,
index d022407..bef47f3 100644 (file)
@@ -40,6 +40,7 @@ static struct scsi_host_template aic94xx_sht = {
        /* .name is initialized */
        .name                   = "aic94xx",
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = sas_slave_configure,
        .scan_finished          = asd_scan_finished,
index 2e1718f..09a7669 100644 (file)
@@ -1756,6 +1756,7 @@ static struct scsi_host_template sht_v1_hw = {
        .proc_name              = DRV_NAME,
        .module                 = THIS_MODULE,
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = hisi_sas_slave_configure,
        .scan_finished          = hisi_sas_scan_finished,
index e7e7849..968d387 100644 (file)
@@ -3532,6 +3532,7 @@ static struct scsi_host_template sht_v2_hw = {
        .proc_name              = DRV_NAME,
        .module                 = THIS_MODULE,
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = hisi_sas_slave_configure,
        .scan_finished          = hisi_sas_scan_finished,
index 3e6b78a..55e2321 100644 (file)
@@ -3075,6 +3075,7 @@ static struct scsi_host_template sht_v3_hw = {
        .proc_name              = DRV_NAME,
        .module                 = THIS_MODULE,
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = hisi_sas_slave_configure,
        .scan_finished          = hisi_sas_scan_finished,
index 7d77997..7d86f4c 100644 (file)
@@ -6731,6 +6731,7 @@ static struct scsi_host_template driver_template = {
        .compat_ioctl = ipr_ioctl,
 #endif
        .queuecommand = ipr_queuecommand,
+       .dma_need_drain = ata_scsi_dma_need_drain,
        .eh_abort_handler = ipr_eh_abort,
        .eh_device_reset_handler = ipr_eh_dev_reset,
        .eh_host_reset_handler = ipr_eh_host_reset,
index 974c3b9..085e285 100644 (file)
@@ -153,6 +153,7 @@ static struct scsi_host_template isci_sht = {
        .name                           = DRV_NAME,
        .proc_name                      = DRV_NAME,
        .queuecommand                   = sas_queuecommand,
+       .dma_need_drain                 = ata_scsi_dma_need_drain,
        .target_alloc                   = sas_target_alloc,
        .slave_configure                = sas_slave_configure,
        .scan_finished                  = isci_host_scan_finished,
index 5973eed..b0de3bd 100644 (file)
@@ -33,6 +33,7 @@ static struct scsi_host_template mvs_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = sas_slave_configure,
        .scan_finished          = mvs_scan_finished,
index a8f5344..9e99262 100644 (file)
@@ -87,6 +87,7 @@ static struct scsi_host_template pm8001_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
        .queuecommand           = sas_queuecommand,
+       .dma_need_drain         = ata_scsi_dma_need_drain,
        .target_alloc           = sas_target_alloc,
        .slave_configure        = sas_slave_configure,
        .scan_finished          = pm8001_scan_finished,
index 53dd876..516a7f5 100644 (file)
@@ -106,8 +106,10 @@ static int ufs_bsg_request(struct bsg_job *job)
                desc_op = bsg_request->upiu_req.qr.opcode;
                ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff,
                                                &desc_len, desc_op);
-               if (ret)
+               if (ret) {
+                       pm_runtime_put_sync(hba->dev);
                        goto out;
+               }
 
                /* fall through */
        case UPIU_TRANSACTION_NOP_OUT:
index 038aec3..a01eda7 100644 (file)
@@ -67,7 +67,7 @@ struct knav_reg_config {
        u32             link_ram_size0;
        u32             link_ram_base1;
        u32             __pad2[2];
-       u32             starvation[0];
+       u32             starvation[];
 };
 
 struct knav_reg_region {
index e8ab583..113116d 100644 (file)
@@ -107,7 +107,7 @@ static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
        /* TG LCD GVSS */
        tosa_tg_send(spi, TG_PINICTL, 0x0);
 
-       if (!data->i2c) {
+       if (IS_ERR_OR_NULL(data->i2c)) {
                /*
                 * after the pannel is powered up the first time,
                 * we can access the i2c bus so probe for the DAC
@@ -119,7 +119,7 @@ static void tosa_lcd_tg_on(struct tosa_lcd_data *data)
                        .addr   = DAC_BASE,
                        .platform_data = data->spi,
                };
-               data->i2c = i2c_new_device(adap, &info);
+               data->i2c = i2c_new_client_device(adap, &info);
        }
 }
 
index f02be0d..8d418ab 100644 (file)
@@ -402,7 +402,7 @@ int __init hpfb_init(void)
        if (err)
                return err;
 
-       err = probe_kernel_read(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1);
+       err = copy_from_kernel_nofault(&i, (unsigned char *)INTFBVADDR + DIO_IDOFF, 1);
 
        if (!err && (i == DIO_ID_FBUFFER) && topcat_sid_ok(sid = DIO_SECID(INTFBVADDR))) {
                if (!request_mem_region(INTFBPADDR, DIO_DEVSIZE, "Internal Topcat"))
index 3041092..449680a 100644 (file)
@@ -73,7 +73,7 @@ struct w1_netlink_msg
                        __u32           res;
                } mst;
        } id;
-       __u8                            data[0];
+       __u8                            data[];
 };
 
 /**
@@ -122,7 +122,7 @@ struct w1_netlink_cmd
        __u8                            cmd;
        __u8                            res;
        __u16                           len;
-       __u8                            data[0];
+       __u8                            data[];
 };
 
 #ifdef __KERNEL__
index aa1d341..96757f3 100644 (file)
@@ -648,7 +648,7 @@ static void afs_do_lookup_success(struct afs_operation *op)
                        vp = &op->file[0];
                        abort_code = vp->scb.status.abort_code;
                        if (abort_code != 0) {
-                               op->abort_code = abort_code;
+                               op->ac.abort_code = abort_code;
                                op->error = afs_abort_to_error(abort_code);
                        }
                        break;
@@ -696,10 +696,11 @@ static const struct afs_operation_ops afs_inline_bulk_status_operation = {
        .success        = afs_do_lookup_success,
 };
 
-static const struct afs_operation_ops afs_fetch_status_operation = {
+static const struct afs_operation_ops afs_lookup_fetch_status_operation = {
        .issue_afs_rpc  = afs_fs_fetch_status,
        .issue_yfs_rpc  = yfs_fs_fetch_status,
        .success        = afs_do_lookup_success,
+       .aborted        = afs_check_for_remote_deletion,
 };
 
 /*
@@ -844,7 +845,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
                 * to FS.FetchStatus for op->file[1].
                 */
                op->fetch_status.which = 1;
-               op->ops = &afs_fetch_status_operation;
+               op->ops = &afs_lookup_fetch_status_operation;
                afs_begin_vnode_operation(op);
                afs_wait_for_operation(op);
        }
@@ -1236,6 +1237,17 @@ void afs_d_release(struct dentry *dentry)
        _enter("%pd", dentry);
 }
 
+void afs_check_for_remote_deletion(struct afs_operation *op)
+{
+       struct afs_vnode *vnode = op->file[0].vnode;
+
+       switch (op->ac.abort_code) {
+       case VNOVNODE:
+               set_bit(AFS_VNODE_DELETED, &vnode->flags);
+               afs_break_callback(vnode, afs_cb_break_for_deleted);
+       }
+}
+
 /*
  * Create a new inode for create/mkdir/symlink
  */
@@ -1268,7 +1280,7 @@ static void afs_vnode_new_inode(struct afs_operation *op)
 static void afs_create_success(struct afs_operation *op)
 {
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, op->file[0].vnode);
+       op->ctime = op->file[0].scb.status.mtime_client;
        afs_vnode_commit_status(op, &op->file[0]);
        afs_update_dentry_version(op, &op->file[0], op->dentry);
        afs_vnode_new_inode(op);
@@ -1302,6 +1314,7 @@ static const struct afs_operation_ops afs_mkdir_operation = {
        .issue_afs_rpc  = afs_fs_make_dir,
        .issue_yfs_rpc  = yfs_fs_make_dir,
        .success        = afs_create_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_create_edit_dir,
        .put            = afs_create_put,
 };
@@ -1325,6 +1338,7 @@ static int afs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 
        afs_op_set_vnode(op, 0, dvnode);
        op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
        op->dentry      = dentry;
        op->create.mode = S_IFDIR | mode;
        op->create.reason = afs_edit_dir_for_mkdir;
@@ -1350,7 +1364,7 @@ static void afs_dir_remove_subdir(struct dentry *dentry)
 static void afs_rmdir_success(struct afs_operation *op)
 {
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, op->file[0].vnode);
+       op->ctime = op->file[0].scb.status.mtime_client;
        afs_vnode_commit_status(op, &op->file[0]);
        afs_update_dentry_version(op, &op->file[0], op->dentry);
 }
@@ -1382,6 +1396,7 @@ static const struct afs_operation_ops afs_rmdir_operation = {
        .issue_afs_rpc  = afs_fs_remove_dir,
        .issue_yfs_rpc  = yfs_fs_remove_dir,
        .success        = afs_rmdir_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_rmdir_edit_dir,
        .put            = afs_rmdir_put,
 };
@@ -1404,6 +1419,7 @@ static int afs_rmdir(struct inode *dir, struct dentry *dentry)
 
        afs_op_set_vnode(op, 0, dvnode);
        op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
 
        op->dentry      = dentry;
        op->ops         = &afs_rmdir_operation;
@@ -1479,7 +1495,8 @@ static void afs_dir_remove_link(struct afs_operation *op)
 static void afs_unlink_success(struct afs_operation *op)
 {
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, op->file[0].vnode);
+       op->ctime = op->file[0].scb.status.mtime_client;
+       afs_check_dir_conflict(op, &op->file[0]);
        afs_vnode_commit_status(op, &op->file[0]);
        afs_vnode_commit_status(op, &op->file[1]);
        afs_update_dentry_version(op, &op->file[0], op->dentry);
@@ -1511,6 +1528,7 @@ static const struct afs_operation_ops afs_unlink_operation = {
        .issue_afs_rpc  = afs_fs_remove_file,
        .issue_yfs_rpc  = yfs_fs_remove_file,
        .success        = afs_unlink_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_unlink_edit_dir,
        .put            = afs_unlink_put,
 };
@@ -1537,6 +1555,7 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
 
        afs_op_set_vnode(op, 0, dvnode);
        op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
 
        /* Try to make sure we have a callback promise on the victim. */
        ret = afs_validate(vnode, op->key);
@@ -1561,9 +1580,25 @@ static int afs_unlink(struct inode *dir, struct dentry *dentry)
        spin_unlock(&dentry->d_lock);
 
        op->file[1].vnode = vnode;
+       op->file[1].update_ctime = true;
+       op->file[1].op_unlinked = true;
        op->dentry      = dentry;
        op->ops         = &afs_unlink_operation;
-       return afs_do_sync_operation(op);
+       afs_begin_vnode_operation(op);
+       afs_wait_for_operation(op);
+
+       /* If there was a conflict with a third party, check the status of the
+        * unlinked vnode.
+        */
+       if (op->error == 0 && (op->flags & AFS_OPERATION_DIR_CONFLICT)) {
+               op->file[1].update_ctime = false;
+               op->fetch_status.which = 1;
+               op->ops = &afs_fetch_status_operation;
+               afs_begin_vnode_operation(op);
+               afs_wait_for_operation(op);
+       }
+
+       return afs_put_operation(op);
 
 error:
        return afs_put_operation(op);
@@ -1573,6 +1608,7 @@ static const struct afs_operation_ops afs_create_operation = {
        .issue_afs_rpc  = afs_fs_create_file,
        .issue_yfs_rpc  = yfs_fs_create_file,
        .success        = afs_create_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_create_edit_dir,
        .put            = afs_create_put,
 };
@@ -1601,6 +1637,7 @@ static int afs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 
        afs_op_set_vnode(op, 0, dvnode);
        op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
 
        op->dentry      = dentry;
        op->create.mode = S_IFREG | mode;
@@ -1620,6 +1657,7 @@ static void afs_link_success(struct afs_operation *op)
        struct afs_vnode_param *vp = &op->file[1];
 
        _enter("op=%08x", op->debug_id);
+       op->ctime = dvp->scb.status.mtime_client;
        afs_vnode_commit_status(op, dvp);
        afs_vnode_commit_status(op, vp);
        afs_update_dentry_version(op, dvp, op->dentry);
@@ -1640,6 +1678,7 @@ static const struct afs_operation_ops afs_link_operation = {
        .issue_afs_rpc  = afs_fs_link,
        .issue_yfs_rpc  = yfs_fs_link,
        .success        = afs_link_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_create_edit_dir,
        .put            = afs_link_put,
 };
@@ -1672,6 +1711,8 @@ static int afs_link(struct dentry *from, struct inode *dir,
        afs_op_set_vnode(op, 0, dvnode);
        afs_op_set_vnode(op, 1, vnode);
        op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
+       op->file[1].update_ctime = true;
 
        op->dentry              = dentry;
        op->dentry_2            = from;
@@ -1689,6 +1730,7 @@ static const struct afs_operation_ops afs_symlink_operation = {
        .issue_afs_rpc  = afs_fs_symlink,
        .issue_yfs_rpc  = yfs_fs_symlink,
        .success        = afs_create_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_create_edit_dir,
        .put            = afs_create_put,
 };
@@ -1740,9 +1782,13 @@ static void afs_rename_success(struct afs_operation *op)
 {
        _enter("op=%08x", op->debug_id);
 
+       op->ctime = op->file[0].scb.status.mtime_client;
+       afs_check_dir_conflict(op, &op->file[1]);
        afs_vnode_commit_status(op, &op->file[0]);
-       if (op->file[1].vnode != op->file[0].vnode)
+       if (op->file[1].vnode != op->file[0].vnode) {
+               op->ctime = op->file[1].scb.status.mtime_client;
                afs_vnode_commit_status(op, &op->file[1]);
+       }
 }
 
 static void afs_rename_edit_dir(struct afs_operation *op)
@@ -1860,6 +1906,8 @@ static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
        afs_op_set_vnode(op, 1, new_dvnode); /* May be same as orig_dvnode */
        op->file[0].dv_delta = 1;
        op->file[1].dv_delta = 1;
+       op->file[0].update_ctime = true;
+       op->file[1].update_ctime = true;
 
        op->dentry              = old_dentry;
        op->dentry_2            = new_dentry;
index b14e3d9..04f75a4 100644 (file)
@@ -16,6 +16,7 @@ static void afs_silly_rename_success(struct afs_operation *op)
 {
        _enter("op=%08x", op->debug_id);
 
+       afs_check_dir_conflict(op, &op->file[0]);
        afs_vnode_commit_status(op, &op->file[0]);
 }
 
@@ -69,6 +70,11 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode
                return PTR_ERR(op);
 
        afs_op_set_vnode(op, 0, dvnode);
+       afs_op_set_vnode(op, 1, dvnode);
+       op->file[0].dv_delta = 1;
+       op->file[1].dv_delta = 1;
+       op->file[0].update_ctime = true;
+       op->file[1].update_ctime = true;
 
        op->dentry              = old;
        op->dentry_2            = new;
@@ -129,6 +135,7 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode,
        switch (ret) {
        case 0:
                /* The rename succeeded. */
+               set_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags);
                d_move(dentry, sdentry);
                break;
        case -ERESTARTSYS:
@@ -148,19 +155,11 @@ out:
 
 static void afs_silly_unlink_success(struct afs_operation *op)
 {
-       struct afs_vnode *vnode = op->file[1].vnode;
-
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, op->file[0].vnode);
+       afs_check_dir_conflict(op, &op->file[0]);
        afs_vnode_commit_status(op, &op->file[0]);
        afs_vnode_commit_status(op, &op->file[1]);
        afs_update_dentry_version(op, &op->file[0], op->dentry);
-
-       drop_nlink(&vnode->vfs_inode);
-       if (vnode->vfs_inode.i_nlink == 0) {
-               set_bit(AFS_VNODE_DELETED, &vnode->flags);
-               clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
-       }
 }
 
 static void afs_silly_unlink_edit_dir(struct afs_operation *op)
@@ -181,6 +180,7 @@ static const struct afs_operation_ops afs_silly_unlink_operation = {
        .issue_afs_rpc  = afs_fs_remove_file,
        .issue_yfs_rpc  = yfs_fs_remove_file,
        .success        = afs_silly_unlink_success,
+       .aborted        = afs_check_for_remote_deletion,
        .edit_dir       = afs_silly_unlink_edit_dir,
 };
 
@@ -200,12 +200,30 @@ static int afs_do_silly_unlink(struct afs_vnode *dvnode, struct afs_vnode *vnode
 
        afs_op_set_vnode(op, 0, dvnode);
        afs_op_set_vnode(op, 1, vnode);
+       op->file[0].dv_delta = 1;
+       op->file[0].update_ctime = true;
+       op->file[1].op_unlinked = true;
+       op->file[1].update_ctime = true;
 
        op->dentry      = dentry;
        op->ops         = &afs_silly_unlink_operation;
 
        trace_afs_silly_rename(vnode, true);
-       return afs_do_sync_operation(op);
+       afs_begin_vnode_operation(op);
+       afs_wait_for_operation(op);
+
+       /* If there was a conflict with a third party, check the status of the
+        * unlinked vnode.
+        */
+       if (op->error == 0 && (op->flags & AFS_OPERATION_DIR_CONFLICT)) {
+               op->file[1].update_ctime = false;
+               op->fetch_status.which = 1;
+               op->ops = &afs_fetch_status_operation;
+               afs_begin_vnode_operation(op);
+               afs_wait_for_operation(op);
+       }
+
+       return afs_put_operation(op);
 }
 
 /*
index 506c474..6f6ed16 100644 (file)
@@ -225,7 +225,6 @@ static void afs_fetch_data_success(struct afs_operation *op)
        struct afs_vnode *vnode = op->file[0].vnode;
 
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, vnode);
        afs_vnode_commit_status(op, &op->file[0]);
        afs_stat_v(vnode, n_fetches);
        atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes);
@@ -240,6 +239,7 @@ static const struct afs_operation_ops afs_fetch_data_operation = {
        .issue_afs_rpc  = afs_fs_fetch_data,
        .issue_yfs_rpc  = yfs_fs_fetch_data,
        .success        = afs_fetch_data_success,
+       .aborted        = afs_check_for_remote_deletion,
        .put            = afs_fetch_data_put,
 };
 
index 71eea2a..ffb8575 100644 (file)
@@ -175,10 +175,7 @@ static void afs_kill_lockers_enoent(struct afs_vnode *vnode)
 
 static void afs_lock_success(struct afs_operation *op)
 {
-       struct afs_vnode *vnode = op->file[0].vnode;
-
        _enter("op=%08x", op->debug_id);
-       afs_check_for_remote_deletion(op, vnode);
        afs_vnode_commit_status(op, &op->file[0]);
 }
 
@@ -186,6 +183,7 @@ static const struct afs_operation_ops afs_set_lock_operation = {
        .issue_afs_rpc  = afs_fs_set_lock,
        .issue_yfs_rpc  = yfs_fs_set_lock,
        .success        = afs_lock_success,
+       .aborted        = afs_check_for_remote_deletion,
 };
 
 /*
index 2d2dff5..c264839 100644 (file)
@@ -187,9 +187,17 @@ void afs_wait_for_operation(struct afs_operation *op)
                op->error = afs_wait_for_call_to_complete(op->call, &op->ac);
        }
 
-       if (op->error == 0) {
+       switch (op->error) {
+       case 0:
                _debug("success");
                op->ops->success(op);
+               break;
+       case -ECONNABORTED:
+               if (op->ops->aborted)
+                       op->ops->aborted(op);
+               break;
+       default:
+               break;
        }
 
        afs_end_vnode_operation(op);
index b34f74b..5d9ef51 100644 (file)
@@ -314,7 +314,7 @@ void afs_fs_probe_timer(struct timer_list *timer)
 {
        struct afs_net *net = container_of(timer, struct afs_net, fs_probe_timer);
 
-       if (!queue_work(afs_wq, &net->fs_prober))
+       if (!net->live || !queue_work(afs_wq, &net->fs_prober))
                afs_dec_servers_outstanding(net);
 }
 
@@ -458,3 +458,12 @@ dont_wait:
                return -ETIME;
        return -EDESTADDRREQ;
 }
+
+/*
+ * Clean up the probing when the namespace is killed off.
+ */
+void afs_fs_probe_cleanup(struct afs_net *net)
+{
+       if (del_timer_sync(&net->fs_probe_timer))
+               afs_dec_servers_outstanding(net);
+}
index cd0a006..1d13d2e 100644 (file)
@@ -165,9 +165,11 @@ static void afs_apply_status(struct afs_operation *op,
 {
        struct afs_file_status *status = &vp->scb.status;
        struct afs_vnode *vnode = vp->vnode;
+       struct inode *inode = &vnode->vfs_inode;
        struct timespec64 t;
        umode_t mode;
        bool data_changed = false;
+       bool change_size = vp->set_size;
 
        _enter("{%llx:%llu.%u} %s",
               vp->fid.vid, vp->fid.vnode, vp->fid.unique,
@@ -186,25 +188,25 @@ static void afs_apply_status(struct afs_operation *op,
        }
 
        if (status->nlink != vnode->status.nlink)
-               set_nlink(&vnode->vfs_inode, status->nlink);
+               set_nlink(inode, status->nlink);
 
        if (status->owner != vnode->status.owner)
-               vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);
+               inode->i_uid = make_kuid(&init_user_ns, status->owner);
 
        if (status->group != vnode->status.group)
-               vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);
+               inode->i_gid = make_kgid(&init_user_ns, status->group);
 
        if (status->mode != vnode->status.mode) {
-               mode = vnode->vfs_inode.i_mode;
+               mode = inode->i_mode;
                mode &= ~S_IALLUGO;
                mode |= status->mode;
-               WRITE_ONCE(vnode->vfs_inode.i_mode, mode);
+               WRITE_ONCE(inode->i_mode, mode);
        }
 
        t = status->mtime_client;
-       vnode->vfs_inode.i_ctime = t;
-       vnode->vfs_inode.i_mtime = t;
-       vnode->vfs_inode.i_atime = t;
+       inode->i_mtime = t;
+       if (vp->update_ctime)
+               inode->i_ctime = op->ctime;
 
        if (vnode->status.data_version != status->data_version)
                data_changed = true;
@@ -226,6 +228,7 @@ static void afs_apply_status(struct afs_operation *op,
                } else {
                        set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
                }
+               change_size = true;
        } else if (vnode->status.type == AFS_FTYPE_DIR) {
                /* Expected directory change is handled elsewhere so
                 * that we can locally edit the directory and save on a
@@ -233,11 +236,22 @@ static void afs_apply_status(struct afs_operation *op,
                 */
                if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
                        data_changed = false;
+               change_size = true;
        }
 
        if (data_changed) {
-               inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
-               afs_set_i_size(vnode, status->size);
+               inode_set_iversion_raw(inode, status->data_version);
+
+               /* Only update the size if the data version jumped.  If the
+                * file is being modified locally, then we might have our own
+                * idea of what the size should be that's not the same as
+                * what's on the server.
+                */
+               if (change_size) {
+                       afs_set_i_size(vnode, status->size);
+                       inode->i_ctime = t;
+                       inode->i_atime = t;
+               }
        }
 }
 
@@ -267,32 +281,39 @@ void afs_vnode_commit_status(struct afs_operation *op, struct afs_vnode_param *v
 
        _enter("");
 
-       ASSERTCMP(op->error, ==, 0);
-
        write_seqlock(&vnode->cb_lock);
 
        if (vp->scb.have_error) {
+               /* A YFS server will return this from RemoveFile2 and AFS and
+                * YFS will return this from InlineBulkStatus.
+                */
                if (vp->scb.status.abort_code == VNOVNODE) {
                        set_bit(AFS_VNODE_DELETED, &vnode->flags);
                        clear_nlink(&vnode->vfs_inode);
                        __afs_break_callback(vnode, afs_cb_break_for_deleted);
+                       op->flags &= ~AFS_OPERATION_DIR_CONFLICT;
                }
-       } else {
-               if (vp->scb.have_status)
-                       afs_apply_status(op, vp);
+       } else if (vp->scb.have_status) {
+               afs_apply_status(op, vp);
                if (vp->scb.have_cb)
                        afs_apply_callback(op, vp);
+       } else if (vp->op_unlinked && !(op->flags & AFS_OPERATION_DIR_CONFLICT)) {
+               drop_nlink(&vnode->vfs_inode);
+               if (vnode->vfs_inode.i_nlink == 0) {
+                       set_bit(AFS_VNODE_DELETED, &vnode->flags);
+                       __afs_break_callback(vnode, afs_cb_break_for_deleted);
+               }
        }
 
        write_sequnlock(&vnode->cb_lock);
 
-       if (op->error == 0 && vp->scb.have_status)
+       if (vp->scb.have_status)
                afs_cache_permit(vnode, op->key, vp->cb_break_before, &vp->scb);
 }
 
 static void afs_fetch_status_success(struct afs_operation *op)
 {
-       struct afs_vnode_param *vp = &op->file[0];
+       struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
        struct afs_vnode *vnode = vp->vnode;
        int ret;
 
@@ -306,10 +327,11 @@ static void afs_fetch_status_success(struct afs_operation *op)
        }
 }
 
-static const struct afs_operation_ops afs_fetch_status_operation = {
+const struct afs_operation_ops afs_fetch_status_operation = {
        .issue_afs_rpc  = afs_fs_fetch_status,
        .issue_yfs_rpc  = yfs_fs_fetch_status,
        .success        = afs_fetch_status_success,
+       .aborted        = afs_check_for_remote_deletion,
 };
 
 /*
@@ -716,6 +738,9 @@ int afs_getattr(const struct path *path, struct kstat *stat,
        do {
                read_seqbegin_or_lock(&vnode->cb_lock, &seq);
                generic_fillattr(inode, stat);
+               if (test_bit(AFS_VNODE_SILLY_DELETED, &vnode->flags) &&
+                   stat->nlink > 0)
+                       stat->nlink -= 1;
        } while (need_seqretry(&vnode->cb_lock, seq));
 
        done_seqretry(&vnode->cb_lock, seq);
@@ -785,7 +810,15 @@ void afs_evict_inode(struct inode *inode)
 
 static void afs_setattr_success(struct afs_operation *op)
 {
+       struct inode *inode = &op->file[0].vnode->vfs_inode;
+
        afs_vnode_commit_status(op, &op->file[0]);
+       if (op->setattr.attr->ia_valid & ATTR_SIZE) {
+               loff_t i_size = inode->i_size, size = op->setattr.attr->ia_size;
+               if (size > i_size)
+                       pagecache_isize_extended(inode, i_size, size);
+               truncate_pagecache(inode, size);
+       }
 }
 
 static const struct afs_operation_ops afs_setattr_operation = {
@@ -801,17 +834,31 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct afs_operation *op;
        struct afs_vnode *vnode = AFS_FS_I(d_inode(dentry));
+       int ret;
 
        _enter("{%llx:%llu},{n=%pd},%x",
               vnode->fid.vid, vnode->fid.vnode, dentry,
               attr->ia_valid);
 
        if (!(attr->ia_valid & (ATTR_SIZE | ATTR_MODE | ATTR_UID | ATTR_GID |
-                               ATTR_MTIME))) {
+                               ATTR_MTIME | ATTR_MTIME_SET | ATTR_TIMES_SET |
+                               ATTR_TOUCH))) {
                _leave(" = 0 [unsupported]");
                return 0;
        }
 
+       if (attr->ia_valid & ATTR_SIZE) {
+               if (!S_ISREG(vnode->vfs_inode.i_mode))
+                       return -EISDIR;
+
+               ret = inode_newsize_ok(&vnode->vfs_inode, attr->ia_size);
+               if (ret)
+                       return ret;
+
+               if (attr->ia_size == i_size_read(&vnode->vfs_inode))
+                       attr->ia_valid &= ~ATTR_SIZE;
+       }
+
        /* flush any dirty data outstanding on a regular file */
        if (S_ISREG(vnode->vfs_inode.i_mode))
                filemap_write_and_wait(vnode->vfs_inode.i_mapping);
@@ -825,8 +872,12 @@ int afs_setattr(struct dentry *dentry, struct iattr *attr)
        afs_op_set_vnode(op, 0, vnode);
        op->setattr.attr = attr;
 
-       if (attr->ia_valid & ATTR_SIZE)
+       if (attr->ia_valid & ATTR_SIZE) {
                op->file[0].dv_delta = 1;
+               op->file[0].set_size = true;
+       }
+       op->ctime = attr->ia_ctime;
+       op->file[0].update_ctime = 1;
 
        op->ops = &afs_setattr_operation;
        return afs_do_sync_operation(op);
index 0c9806e..d520535 100644 (file)
@@ -634,6 +634,7 @@ struct afs_vnode {
 #define AFS_VNODE_AUTOCELL     6               /* set if Vnode is an auto mount point */
 #define AFS_VNODE_PSEUDODIR    7               /* set if Vnode is a pseudo directory */
 #define AFS_VNODE_NEW_CONTENT  8               /* Set if file has new content (create/trunc-0) */
+#define AFS_VNODE_SILLY_DELETED        9               /* Set if file has been silly-deleted */
 
        struct list_head        wb_keys;        /* List of keys available for writeback */
        struct list_head        pending_locks;  /* locks waiting to be granted */
@@ -744,8 +745,11 @@ struct afs_vnode_param {
        afs_dataversion_t       dv_before;      /* Data version before the call */
        unsigned int            cb_break_before; /* cb_break + cb_s_break before the call */
        u8                      dv_delta;       /* Expected change in data version */
-       bool                    put_vnode;      /* T if we have a ref on the vnode */
-       bool                    need_io_lock;   /* T if we need the I/O lock on this */
+       bool                    put_vnode:1;    /* T if we have a ref on the vnode */
+       bool                    need_io_lock:1; /* T if we need the I/O lock on this */
+       bool                    update_ctime:1; /* Need to update the ctime */
+       bool                    set_size:1;     /* Must update i_size */
+       bool                    op_unlinked:1;  /* True if file was unlinked by op */
 };
 
 /*
@@ -766,9 +770,9 @@ struct afs_operation {
        struct dentry           *dentry;        /* Dentry to be altered */
        struct dentry           *dentry_2;      /* Second dentry to be altered */
        struct timespec64       mtime;          /* Modification time to record */
+       struct timespec64       ctime;          /* Change time to set */
        short                   nr_files;       /* Number of entries in file[], more_files */
        short                   error;
-       unsigned int            abort_code;
        unsigned int            debug_id;
 
        unsigned int            cb_v_break;     /* Volume break counter before op */
@@ -837,6 +841,7 @@ struct afs_operation {
 #define AFS_OPERATION_LOCK_1           0x0200  /* Set if have io_lock on file[1] */
 #define AFS_OPERATION_TRIED_ALL                0x0400  /* Set if we've tried all the fileservers */
 #define AFS_OPERATION_RETRY_SERVER     0x0800  /* Set if we should retry the current server */
+#define AFS_OPERATION_DIR_CONFLICT     0x1000  /* Set if we detected a 3rd-party dir change */
 };
 
 /*
@@ -932,6 +937,7 @@ extern const struct address_space_operations afs_dir_aops;
 extern const struct dentry_operations afs_fs_dentry_operations;
 
 extern void afs_d_release(struct dentry *);
+extern void afs_check_for_remote_deletion(struct afs_operation *);
 
 /*
  * dir_edit.c
@@ -1059,10 +1065,13 @@ extern int afs_wait_for_fs_probes(struct afs_server_list *, unsigned long);
 extern void afs_probe_fileserver(struct afs_net *, struct afs_server *);
 extern void afs_fs_probe_dispatcher(struct work_struct *);
 extern int afs_wait_for_one_fs_probe(struct afs_server *, bool);
+extern void afs_fs_probe_cleanup(struct afs_net *);
 
 /*
  * inode.c
  */
+extern const struct afs_operation_ops afs_fetch_status_operation;
+
 extern void afs_vnode_commit_status(struct afs_operation *, struct afs_vnode_param *);
 extern int afs_fetch_status(struct afs_vnode *, struct key *, bool, afs_access_t *);
 extern int afs_ilookup5_test_by_fid(struct inode *, void *);
@@ -1435,7 +1444,6 @@ extern ssize_t afs_listxattr(struct dentry *, char *, size_t);
 /*
  * yfsclient.c
  */
-extern void yfs_fs_fetch_file_status(struct afs_operation *);
 extern void yfs_fs_fetch_data(struct afs_operation *);
 extern void yfs_fs_create_file(struct afs_operation *);
 extern void yfs_fs_make_dir(struct afs_operation *);
@@ -1481,15 +1489,6 @@ static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode)
        return &vnode->vfs_inode;
 }
 
-static inline void afs_check_for_remote_deletion(struct afs_operation *op,
-                                                struct afs_vnode *vnode)
-{
-       if (op->error == -ENOENT) {
-               set_bit(AFS_VNODE_DELETED, &vnode->flags);
-               afs_break_callback(vnode, afs_cb_break_for_deleted);
-       }
-}
-
 /*
  * Note that a dentry got changed.  We need to set d_fsdata to the data version
  * number derived from the result of the operation.  It doesn't matter if
@@ -1504,6 +1503,18 @@ static inline void afs_update_dentry_version(struct afs_operation *op,
                        (void *)(unsigned long)dir_vp->scb.status.data_version;
 }
 
+/*
+ * Check for a conflicting operation on a directory that we just unlinked from.
+ * If someone managed to sneak a link or an unlink in on the file we just
+ * unlinked, we won't be able to trust nlink on an AFS file (but not YFS).
+ */
+static inline void afs_check_dir_conflict(struct afs_operation *op,
+                                         struct afs_vnode_param *dvp)
+{
+       if (dvp->dv_before + dvp->dv_delta != dvp->scb.status.data_version)
+               op->flags |= AFS_OPERATION_DIR_CONFLICT;
+}
+
 static inline int afs_io_error(struct afs_call *call, enum afs_io_error where)
 {
        trace_afs_io_error(call->debug_id, -EIO, where);
index 9c79c91..31b472f 100644 (file)
@@ -100,6 +100,7 @@ static int __net_init afs_net_init(struct net *net_ns)
        timer_setup(&net->fs_timer, afs_servers_timer, 0);
        INIT_WORK(&net->fs_prober, afs_fs_probe_dispatcher);
        timer_setup(&net->fs_probe_timer, afs_fs_probe_timer, 0);
+       atomic_set(&net->servers_outstanding, 1);
 
        ret = -ENOMEM;
        sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL);
@@ -130,6 +131,7 @@ static int __net_init afs_net_init(struct net *net_ns)
 
 error_open_socket:
        net->live = false;
+       afs_fs_probe_cleanup(net);
        afs_cell_purge(net);
        afs_purge_servers(net);
 error_cell_init:
@@ -150,6 +152,7 @@ static void __net_exit afs_net_exit(struct net *net_ns)
        struct afs_net *net = afs_net(net_ns);
 
        net->live = false;
+       afs_fs_probe_cleanup(net);
        afs_cell_purge(net);
        afs_purge_servers(net);
        afs_close_socket(net);
index 52b19e9..5334f1b 100644 (file)
@@ -83,6 +83,7 @@ int afs_abort_to_error(u32 abort_code)
        case UAENOLCK:                  return -ENOLCK;
        case UAENOTEMPTY:               return -ENOTEMPTY;
        case UAELOOP:                   return -ELOOP;
+       case UAEOVERFLOW:               return -EOVERFLOW;
        case UAENOMEDIUM:               return -ENOMEDIUM;
        case UAEDQUOT:                  return -EDQUOT;
 
index 039e348..e82e452 100644 (file)
@@ -605,11 +605,12 @@ void afs_purge_servers(struct afs_net *net)
        _enter("");
 
        if (del_timer_sync(&net->fs_timer))
-               atomic_dec(&net->servers_outstanding);
+               afs_dec_servers_outstanding(net);
 
        afs_queue_server_manager(net);
 
        _debug("wait");
+       atomic_dec(&net->servers_outstanding);
        wait_var_event(&net->servers_outstanding,
                       !atomic_read(&net->servers_outstanding));
        _leave("");
index 768497f..7437806 100644 (file)
@@ -194,11 +194,11 @@ int afs_write_end(struct file *file, struct address_space *mapping,
 
        i_size = i_size_read(&vnode->vfs_inode);
        if (maybe_i_size > i_size) {
-               spin_lock(&vnode->wb_lock);
+               write_seqlock(&vnode->cb_lock);
                i_size = i_size_read(&vnode->vfs_inode);
                if (maybe_i_size > i_size)
                        i_size_write(&vnode->vfs_inode, maybe_i_size);
-               spin_unlock(&vnode->wb_lock);
+               write_sequnlock(&vnode->cb_lock);
        }
 
        if (!PageUptodate(page)) {
@@ -393,6 +393,7 @@ static void afs_store_data_success(struct afs_operation *op)
 {
        struct afs_vnode *vnode = op->file[0].vnode;
 
+       op->ctime = op->file[0].scb.status.mtime_client;
        afs_vnode_commit_status(op, &op->file[0]);
        if (op->error == 0) {
                afs_pages_written_back(vnode, op->store.first, op->store.last);
@@ -491,6 +492,7 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
        unsigned long count, priv;
        unsigned n, offset, to, f, t;
        pgoff_t start, first, last;
+       loff_t i_size, end;
        int loop, ret;
 
        _enter(",%lx", primary_page->index);
@@ -591,7 +593,12 @@ no_more:
        first = primary_page->index;
        last = first + count - 1;
 
+       end = (loff_t)last * PAGE_SIZE + to;
+       i_size = i_size_read(&vnode->vfs_inode);
+
        _debug("write back %lx[%u..] to %lx[..%u]", first, offset, last, to);
+       if (end > i_size)
+               to = i_size & ~PAGE_MASK;
 
        ret = afs_store_data(mapping, first, last, offset, to);
        switch (ret) {
@@ -844,6 +851,7 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)
                             vmf->page->index, priv);
        SetPagePrivate(vmf->page);
        set_page_private(vmf->page, priv);
+       file_update_time(file);
 
        sb_end_pagefault(inode->i_sb);
        return VM_FAULT_LOCKED;
index 52d5af5..8c24fdc 100644 (file)
@@ -329,29 +329,6 @@ static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
        *_bp += sizeof(*x) / sizeof(__be32);
 }
 
-/*
- * Deliver a reply that's a status, callback and volsync.
- */
-static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
-{
-       struct afs_operation *op = call->op;
-       const __be32 *bp;
-       int ret;
-
-       ret = afs_transfer_reply(call);
-       if (ret < 0)
-               return ret;
-
-       /* unmarshall the reply once we've received all of it */
-       bp = call->buffer;
-       xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
-       xdr_decode_YFSCallBack(&bp, call, &op->file[0].scb);
-       xdr_decode_YFSVolSync(&bp, &op->volsync);
-
-       _leave(" = 0 [done]");
-       return 0;
-}
-
 /*
  * Deliver reply data to operations that just return a file status and a volume
  * sync record.
@@ -374,48 +351,6 @@ static int yfs_deliver_status_and_volsync(struct afs_call *call)
        return 0;
 }
 
-/*
- * YFS.FetchStatus operation type
- */
-static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
-       .name           = "YFS.FetchStatus(vnode)",
-       .op             = yfs_FS_FetchStatus,
-       .deliver        = yfs_deliver_fs_status_cb_and_volsync,
-       .destructor     = afs_flat_call_destructor,
-};
-
-/*
- * Fetch the status information for a file.
- */
-void yfs_fs_fetch_file_status(struct afs_operation *op)
-{
-       struct afs_vnode_param *vp = &op->file[0];
-       struct afs_call *call;
-       __be32 *bp;
-
-       _enter(",%x,{%llx:%llu},,",
-              key_serial(op->key), vp->fid.vid, vp->fid.vnode);
-
-       call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus_vnode,
-                                  sizeof(__be32) * 2 +
-                                  sizeof(struct yfs_xdr_YFSFid),
-                                  sizeof(struct yfs_xdr_YFSFetchStatus) +
-                                  sizeof(struct yfs_xdr_YFSCallBack) +
-                                  sizeof(struct yfs_xdr_YFSVolSync));
-       if (!call)
-               return afs_op_nomem(op);
-
-       /* marshall the parameters */
-       bp = call->request;
-       bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
-       bp = xdr_encode_u32(bp, 0); /* RPC flags */
-       bp = xdr_encode_YFSFid(bp, &vp->fid);
-       yfs_check_req(call, bp);
-
-       trace_afs_make_fs_call(call, &vp->fid);
-       afs_make_op_call(op, call, GFP_NOFS);
-}
-
 /*
  * Deliver reply data to an YFS.FetchData64.
  */
@@ -1604,13 +1539,37 @@ void yfs_fs_release_lock(struct afs_operation *op)
        afs_make_op_call(op, call, GFP_NOFS);
 }
 
+/*
+ * Deliver a reply to YFS.FetchStatus
+ */
+static int yfs_deliver_fs_fetch_status(struct afs_call *call)
+{
+       struct afs_operation *op = call->op;
+       struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
+       const __be32 *bp;
+       int ret;
+
+       ret = afs_transfer_reply(call);
+       if (ret < 0)
+               return ret;
+
+       /* unmarshall the reply once we've received all of it */
+       bp = call->buffer;
+       xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
+       xdr_decode_YFSCallBack(&bp, call, &vp->scb);
+       xdr_decode_YFSVolSync(&bp, &op->volsync);
+
+       _leave(" = 0 [done]");
+       return 0;
+}
+
 /*
  * YFS.FetchStatus operation type
  */
 static const struct afs_call_type yfs_RXYFSFetchStatus = {
        .name           = "YFS.FetchStatus",
        .op             = yfs_FS_FetchStatus,
-       .deliver        = yfs_deliver_fs_status_cb_and_volsync,
+       .deliver        = yfs_deliver_fs_fetch_status,
        .destructor     = afs_flat_call_destructor,
 };
 
@@ -1619,7 +1578,7 @@ static const struct afs_call_type yfs_RXYFSFetchStatus = {
  */
 void yfs_fs_fetch_status(struct afs_operation *op)
 {
-       struct afs_vnode_param *vp = &op->file[0];
+       struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
        struct afs_call *call;
        __be32 *bp;
 
index 7ecddc2..91e7cc4 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -67,7 +67,7 @@ struct aio_ring {
        unsigned        header_length;  /* size of aio_ring */
 
 
-       struct io_event         io_events[0];
+       struct io_event         io_events[];
 }; /* 128 bytes + ring size */
 
 /*
index 47860e5..0ae656e 100644 (file)
@@ -75,7 +75,7 @@ static void bdev_write_inode(struct block_device *bdev)
 }
 
 /* Kill _all_ buffers and pagecache , dirty or not.. */
-void kill_bdev(struct block_device *bdev)
+static void kill_bdev(struct block_device *bdev)
 {
        struct address_space *mapping = bdev->bd_inode->i_mapping;
 
@@ -84,8 +84,7 @@ void kill_bdev(struct block_device *bdev)
 
        invalidate_bh_lrus();
        truncate_inode_pages(mapping, 0);
-}      
-EXPORT_SYMBOL(kill_bdev);
+}
 
 /* Invalidate clean unused buffers and pagecache. */
 void invalidate_bdev(struct block_device *bdev)
@@ -1565,10 +1564,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
         */
        if (!for_part) {
                ret = devcgroup_inode_permission(bdev->bd_inode, perm);
-               if (ret != 0) {
-                       bdput(bdev);
+               if (ret != 0)
                        return ret;
-               }
        }
 
  restart:
@@ -1637,8 +1634,10 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
                                goto out_clear;
                        BUG_ON(for_part);
                        ret = __blkdev_get(whole, mode, 1);
-                       if (ret)
+                       if (ret) {
+                               bdput(whole);
                                goto out_clear;
+                       }
                        bdev->bd_contains = whole;
                        bdev->bd_part = disk_get_part(disk, partno);
                        if (!(disk->flags & GENHD_FL_UP) ||
@@ -1688,7 +1687,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
        disk_unblock_events(disk);
        put_disk_and_module(disk);
  out:
-       bdput(bdev);
 
        return ret;
 }
@@ -1755,6 +1753,9 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
                bdput(whole);
        }
 
+       if (res)
+               bdput(bdev);
+
        return res;
 }
 EXPORT_SYMBOL(blkdev_get);
index 4ccb3c9..2e42f47 100644 (file)
@@ -9,7 +9,8 @@ ext4-y  := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
                extents_status.o file.o fsmap.o fsync.o hash.o ialloc.o \
                indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \
                mmp.o move_extent.o namei.o page-io.o readpage.o resize.o \
-               super.o symlink.o sysfs.o xattr.o xattr_trusted.o xattr_user.o
+               super.o symlink.o sysfs.o xattr.o xattr_hurd.o xattr_trusted.o \
+               xattr_user.o
 
 ext4-$(CONFIG_EXT4_FS_POSIX_ACL)       += acl.o
 ext4-$(CONFIG_EXT4_FS_SECURITY)                += xattr_security.o
index c654205..1d82336 100644 (file)
@@ -675,6 +675,7 @@ static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
        struct qstr qstr = {.name = str, .len = len };
        const struct dentry *parent = READ_ONCE(dentry->d_parent);
        const struct inode *inode = READ_ONCE(parent->d_inode);
+       char strbuf[DNAME_INLINE_LEN];
 
        if (!inode || !IS_CASEFOLDED(inode) ||
            !EXT4_SB(inode->i_sb)->s_encoding) {
@@ -683,6 +684,21 @@ static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
                return memcmp(str, name->name, len);
        }
 
+       /*
+        * If the dentry name is stored in-line, then it may be concurrently
+        * modified by a rename.  If this happens, the VFS will eventually retry
+        * the lookup, so it doesn't matter what ->d_compare() returns.
+        * However, it's unsafe to call utf8_strncasecmp() with an unstable
+        * string.  Therefore, we have to copy the name into a temporary buffer.
+        */
+       if (len <= DNAME_INLINE_LEN - 1) {
+               memcpy(strbuf, str, len);
+               strbuf[len] = 0;
+               qstr.name = strbuf;
+               /* prevent compiler from optimizing out the temporary buffer */
+               barrier();
+       }
+
        return ext4_ci_compare(inode, name, &qstr, false);
 }
 
index b08841f..42f5060 100644 (file)
@@ -426,13 +426,16 @@ struct flex_groups {
 #define EXT4_VERITY_FL                 0x00100000 /* Verity protected inode */
 #define EXT4_EA_INODE_FL               0x00200000 /* Inode used for large EA */
 /* 0x00400000 was formerly EXT4_EOFBLOCKS_FL */
+
+#define EXT4_DAX_FL                    0x02000000 /* Inode is DAX */
+
 #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
 #define EXT4_PROJINHERIT_FL            0x20000000 /* Create with parents projid */
 #define EXT4_CASEFOLD_FL               0x40000000 /* Casefolded directory */
 #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
 
-#define EXT4_FL_USER_VISIBLE           0x705BDFFF /* User visible flags */
-#define EXT4_FL_USER_MODIFIABLE                0x604BC0FF /* User modifiable flags */
+#define EXT4_FL_USER_VISIBLE           0x725BDFFF /* User visible flags */
+#define EXT4_FL_USER_MODIFIABLE                0x624BC0FF /* User modifiable flags */
 
 /* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */
 #define EXT4_FL_XFLAG_VISIBLE          (EXT4_SYNC_FL | \
@@ -440,14 +443,16 @@ struct flex_groups {
                                         EXT4_APPEND_FL | \
                                         EXT4_NODUMP_FL | \
                                         EXT4_NOATIME_FL | \
-                                        EXT4_PROJINHERIT_FL)
+                                        EXT4_PROJINHERIT_FL | \
+                                        EXT4_DAX_FL)
 
 /* Flags that should be inherited by new inodes from their parent. */
 #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\
                           EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
                           EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
                           EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
-                          EXT4_PROJINHERIT_FL | EXT4_CASEFOLD_FL)
+                          EXT4_PROJINHERIT_FL | EXT4_CASEFOLD_FL |\
+                          EXT4_DAX_FL)
 
 /* Flags that are appropriate for regular files (all but dir-specific ones). */
 #define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL | EXT4_CASEFOLD_FL |\
@@ -459,6 +464,10 @@ struct flex_groups {
 /* The only flags that should be swapped */
 #define EXT4_FL_SHOULD_SWAP (EXT4_HUGE_FILE_FL | EXT4_EXTENTS_FL)
 
+/* Flags which are mutually exclusive to DAX */
+#define EXT4_DAX_MUT_EXCL (EXT4_VERITY_FL | EXT4_ENCRYPT_FL |\
+                          EXT4_JOURNAL_DATA_FL)
+
 /* Mask out flags that are inappropriate for the given type of inode. */
 static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
 {
@@ -499,6 +508,7 @@ enum {
        EXT4_INODE_VERITY       = 20,   /* Verity protected inode */
        EXT4_INODE_EA_INODE     = 21,   /* Inode used for large EA */
 /* 22 was formerly EXT4_INODE_EOFBLOCKS */
+       EXT4_INODE_DAX          = 25,   /* Inode is DAX */
        EXT4_INODE_INLINE_DATA  = 28,   /* Data in inode. */
        EXT4_INODE_PROJINHERIT  = 29,   /* Create with parents projid */
        EXT4_INODE_CASEFOLD     = 30,   /* Casefolded directory */
@@ -1135,9 +1145,9 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_MINIX_DF            0x00080 /* Mimics the Minix statfs */
 #define EXT4_MOUNT_NOLOAD              0x00100 /* Don't use existing journal*/
 #ifdef CONFIG_FS_DAX
-#define EXT4_MOUNT_DAX                 0x00200 /* Direct Access */
+#define EXT4_MOUNT_DAX_ALWAYS          0x00200 /* Direct Access */
 #else
-#define EXT4_MOUNT_DAX                 0
+#define EXT4_MOUNT_DAX_ALWAYS          0
 #endif
 #define EXT4_MOUNT_DATA_FLAGS          0x00C00 /* Mode for data writes: */
 #define EXT4_MOUNT_JOURNAL_DATA                0x00400 /* Write data to journal */
@@ -1180,6 +1190,8 @@ struct ext4_inode_info {
                                                      blocks */
 #define EXT4_MOUNT2_HURD_COMPAT                0x00000004 /* Support HURD-castrated
                                                      file systems */
+#define EXT4_MOUNT2_DAX_NEVER          0x00000008 /* Do not allow Direct Access */
+#define EXT4_MOUNT2_DAX_INODE          0x00000010 /* For printing options only */
 
 #define EXT4_MOUNT2_EXPLICIT_JOURNAL_CHECKSUM  0x00000008 /* User explicitly
                                                specified journal checksum */
@@ -1992,6 +2004,7 @@ static inline bool ext4_has_incompat_features(struct super_block *sb)
  */
 #define EXT4_FLAGS_RESIZING    0
 #define EXT4_FLAGS_SHUTDOWN    1
+#define EXT4_FLAGS_BDEV_IS_DAX 2
 
 static inline int ext4_forced_shutdown(struct ext4_sb_info *sbi)
 {
@@ -2705,7 +2718,7 @@ extern int ext4_can_truncate(struct inode *inode);
 extern int ext4_truncate(struct inode *);
 extern int ext4_break_layouts(struct inode *);
 extern int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length);
-extern void ext4_set_inode_flags(struct inode *);
+extern void ext4_set_inode_flags(struct inode *, bool init);
 extern int ext4_alloc_da_blocks(struct inode *inode);
 extern void ext4_set_aops(struct inode *inode);
 extern int ext4_writepage_trans_blocks(struct inode *);
index 7d088ff..221f240 100644 (file)
@@ -2844,7 +2844,7 @@ again:
                         * in use to avoid freeing it when removing blocks.
                         */
                        if (sbi->s_cluster_ratio > 1) {
-                               pblk = ext4_ext_pblock(ex) + end - ee_block + 2;
+                               pblk = ext4_ext_pblock(ex) + end - ee_block + 1;
                                partial.pclu = EXT4_B2C(sbi, pblk);
                                partial.state = nofree;
                        }
index 54d324e..df25d38 100644 (file)
@@ -1116,7 +1116,7 @@ got:
        ei->i_block_group = group;
        ei->i_last_alloc_group = ~0;
 
-       ext4_set_inode_flags(inode);
+       ext4_set_inode_flags(inode, true);
        if (IS_DIRSYNC(inode))
                ext4_handle_sync(handle);
        if (insert_inode_locked(inode) < 0) {
index 40ec5c7..10dd470 100644 (file)
@@ -4403,9 +4403,11 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
                !ext4_test_inode_state(inode, EXT4_STATE_XATTR));
 }
 
-static bool ext4_should_use_dax(struct inode *inode)
+static bool ext4_should_enable_dax(struct inode *inode)
 {
-       if (!test_opt(inode->i_sb, DAX))
+       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+
+       if (test_opt2(inode->i_sb, DAX_NEVER))
                return false;
        if (!S_ISREG(inode->i_mode))
                return false;
@@ -4417,14 +4419,21 @@ static bool ext4_should_use_dax(struct inode *inode)
                return false;
        if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY))
                return false;
-       return true;
+       if (!test_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags))
+               return false;
+       if (test_opt(inode->i_sb, DAX_ALWAYS))
+               return true;
+
+       return ext4_test_inode_flag(inode, EXT4_INODE_DAX);
 }
 
-void ext4_set_inode_flags(struct inode *inode)
+void ext4_set_inode_flags(struct inode *inode, bool init)
 {
        unsigned int flags = EXT4_I(inode)->i_flags;
        unsigned int new_fl = 0;
 
+       WARN_ON_ONCE(IS_DAX(inode) && init);
+
        if (flags & EXT4_SYNC_FL)
                new_fl |= S_SYNC;
        if (flags & EXT4_APPEND_FL)
@@ -4435,8 +4444,13 @@ void ext4_set_inode_flags(struct inode *inode)
                new_fl |= S_NOATIME;
        if (flags & EXT4_DIRSYNC_FL)
                new_fl |= S_DIRSYNC;
-       if (ext4_should_use_dax(inode))
+
+       /* Because of the way inode_set_flags() works we must preserve S_DAX
+        * here if already set. */
+       new_fl |= (inode->i_flags & S_DAX);
+       if (init && ext4_should_enable_dax(inode))
                new_fl |= S_DAX;
+
        if (flags & EXT4_ENCRYPT_FL)
                new_fl |= S_ENCRYPTED;
        if (flags & EXT4_CASEFOLD_FL)
@@ -4650,7 +4664,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
                 * not initialized on a new filesystem. */
        }
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
-       ext4_set_inode_flags(inode);
+       ext4_set_inode_flags(inode, true);
        inode->i_blocks = ext4_inode_blocks(raw_inode, ei);
        ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);
        if (ext4_has_feature_64bit(sb))
index 2162db0..999cf6a 100644 (file)
@@ -292,6 +292,38 @@ static int ext4_ioctl_check_immutable(struct inode *inode, __u32 new_projid,
        return 0;
 }
 
+static void ext4_dax_dontcache(struct inode *inode, unsigned int flags)
+{
+       struct ext4_inode_info *ei = EXT4_I(inode);
+
+       if (S_ISDIR(inode->i_mode))
+               return;
+
+       if (test_opt2(inode->i_sb, DAX_NEVER) ||
+           test_opt(inode->i_sb, DAX_ALWAYS))
+               return;
+
+       if ((ei->i_flags ^ flags) & EXT4_DAX_FL)
+               d_mark_dontcache(inode);
+}
+
+static bool dax_compatible(struct inode *inode, unsigned int oldflags,
+                          unsigned int flags)
+{
+       if (flags & EXT4_DAX_FL) {
+               if ((oldflags & EXT4_DAX_MUT_EXCL) ||
+                    ext4_test_inode_state(inode,
+                                         EXT4_STATE_VERITY_IN_PROGRESS)) {
+                       return false;
+               }
+       }
+
+       if ((flags & EXT4_DAX_MUT_EXCL) && (oldflags & EXT4_DAX_FL))
+                       return false;
+
+       return true;
+}
+
 static int ext4_ioctl_setflags(struct inode *inode,
                               unsigned int flags)
 {
@@ -300,7 +332,6 @@ static int ext4_ioctl_setflags(struct inode *inode,
        int err = -EPERM, migrate = 0;
        struct ext4_iloc iloc;
        unsigned int oldflags, mask, i;
-       unsigned int jflag;
        struct super_block *sb = inode->i_sb;
 
        /* Is it quota file? Do not allow user to mess with it */
@@ -309,9 +340,6 @@ static int ext4_ioctl_setflags(struct inode *inode,
 
        oldflags = ei->i_flags;
 
-       /* The JOURNAL_DATA flag is modifiable only by root */
-       jflag = flags & EXT4_JOURNAL_DATA_FL;
-
        err = vfs_ioc_setflags_prepare(inode, oldflags, flags);
        if (err)
                goto flags_out;
@@ -320,10 +348,16 @@ static int ext4_ioctl_setflags(struct inode *inode,
         * The JOURNAL_DATA flag can only be changed by
         * the relevant capability.
         */
-       if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
+       if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
                if (!capable(CAP_SYS_RESOURCE))
                        goto flags_out;
        }
+
+       if (!dax_compatible(inode, oldflags, flags)) {
+               err = -EOPNOTSUPP;
+               goto flags_out;
+       }
+
        if ((flags ^ oldflags) & EXT4_EXTENTS_FL)
                migrate = 1;
 
@@ -369,6 +403,8 @@ static int ext4_ioctl_setflags(struct inode *inode,
        if (err)
                goto flags_err;
 
+       ext4_dax_dontcache(inode, flags);
+
        for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
                if (!(mask & EXT4_FL_USER_MODIFIABLE))
                        continue;
@@ -381,7 +417,8 @@ static int ext4_ioctl_setflags(struct inode *inode,
                        ext4_clear_inode_flag(inode, i);
        }
 
-       ext4_set_inode_flags(inode);
+       ext4_set_inode_flags(inode, false);
+
        inode->i_ctime = current_time(inode);
 
        err = ext4_mark_iloc_dirty(handle, inode, &iloc);
@@ -390,17 +427,18 @@ flags_err:
        if (err)
                goto flags_out;
 
-       if ((jflag ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
+       if ((flags ^ oldflags) & (EXT4_JOURNAL_DATA_FL)) {
                /*
                 * Changes to the journaling mode can cause unsafe changes to
-                * S_DAX if we are using the DAX mount option.
+                * S_DAX if the inode is DAX
                 */
-               if (test_opt(inode->i_sb, DAX)) {
+               if (IS_DAX(inode)) {
                        err = -EBUSY;
                        goto flags_out;
                }
 
-               err = ext4_change_inode_journal_flag(inode, jflag);
+               err = ext4_change_inode_journal_flag(inode,
+                                                    flags & EXT4_JOURNAL_DATA_FL);
                if (err)
                        goto flags_out;
        }
@@ -527,12 +565,15 @@ static inline __u32 ext4_iflags_to_xflags(unsigned long iflags)
                xflags |= FS_XFLAG_NOATIME;
        if (iflags & EXT4_PROJINHERIT_FL)
                xflags |= FS_XFLAG_PROJINHERIT;
+       if (iflags & EXT4_DAX_FL)
+               xflags |= FS_XFLAG_DAX;
        return xflags;
 }
 
 #define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \
                                  FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \
-                                 FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT)
+                                 FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \
+                                 FS_XFLAG_DAX)
 
 /* Transfer xflags flags to internal */
 static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
@@ -551,6 +592,8 @@ static inline unsigned long ext4_xflags_to_iflags(__u32 xflags)
                iflags |= EXT4_NOATIME_FL;
        if (xflags & FS_XFLAG_PROJINHERIT)
                iflags |= EXT4_PROJINHERIT_FL;
+       if (xflags & FS_XFLAG_DAX)
+               iflags |= EXT4_DAX_FL;
 
        return iflags;
 }
index a908311..c0a331e 100644 (file)
@@ -4708,7 +4708,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
        }
 
        ac->ac_op = EXT4_MB_HISTORY_PREALLOC;
-       seq = *this_cpu_ptr(&discard_pa_seq);
+       seq = this_cpu_read(discard_pa_seq);
        if (!ext4_mb_use_preallocated(ac)) {
                ac->ac_op = EXT4_MB_HISTORY_ALLOC;
                ext4_mb_normalize_request(ac, ar);
index c668f6b..330957e 100644 (file)
@@ -522,9 +522,6 @@ static void ext4_handle_error(struct super_block *sb)
                smp_wmb();
                sb->s_flags |= SB_RDONLY;
        } else if (test_opt(sb, ERRORS_PANIC)) {
-               if (EXT4_SB(sb)->s_journal &&
-                 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
-                       return;
                panic("EXT4-fs (device %s): panic forced after error\n",
                        sb->s_id);
        }
@@ -725,23 +722,20 @@ void __ext4_abort(struct super_block *sb, const char *function,
        va_end(args);
 
        if (sb_rdonly(sb) == 0) {
-               ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
                EXT4_SB(sb)->s_mount_flags |= EXT4_MF_FS_ABORTED;
+               if (EXT4_SB(sb)->s_journal)
+                       jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
+
+               ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only");
                /*
                 * Make sure updated value of ->s_mount_flags will be visible
                 * before ->s_flags update
                 */
                smp_wmb();
                sb->s_flags |= SB_RDONLY;
-               if (EXT4_SB(sb)->s_journal)
-                       jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
        }
-       if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) {
-               if (EXT4_SB(sb)->s_journal &&
-                 !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
-                       return;
+       if (test_opt(sb, ERRORS_PANIC) && !system_going_down())
                panic("EXT4-fs panic from previous error\n");
-       }
 }
 
 void __ext4_msg(struct super_block *sb,
@@ -1324,6 +1318,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
        if (WARN_ON_ONCE(IS_DAX(inode) && i_size_read(inode)))
                return -EINVAL;
 
+       if (ext4_test_inode_flag(inode, EXT4_INODE_DAX))
+               return -EOPNOTSUPP;
+
        res = ext4_convert_inline_data(inode);
        if (res)
                return res;
@@ -1349,7 +1346,7 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
                         * Update inode->i_flags - S_ENCRYPTED will be enabled,
                         * S_DAX may be disabled
                         */
-                       ext4_set_inode_flags(inode);
+                       ext4_set_inode_flags(inode, false);
                }
                return res;
        }
@@ -1376,7 +1373,7 @@ retry:
                 * Update inode->i_flags - S_ENCRYPTED will be enabled,
                 * S_DAX may be disabled
                 */
-               ext4_set_inode_flags(inode);
+               ext4_set_inode_flags(inode, false);
                res = ext4_mark_inode_dirty(handle, inode);
                if (res)
                        EXT4_ERROR_INODE(inode, "Failed to mark inode dirty");
@@ -1514,7 +1511,8 @@ enum {
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
        Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err,
-       Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax,
+       Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version,
+       Opt_dax, Opt_dax_always, Opt_dax_inode, Opt_dax_never,
        Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error,
        Opt_nowarn_on_error, Opt_mblk_io_submit,
        Opt_lazytime, Opt_nolazytime, Opt_debug_want_extra_isize,
@@ -1581,6 +1579,9 @@ static const match_table_t tokens = {
        {Opt_nobarrier, "nobarrier"},
        {Opt_i_version, "i_version"},
        {Opt_dax, "dax"},
+       {Opt_dax_always, "dax=always"},
+       {Opt_dax_inode, "dax=inode"},
+       {Opt_dax_never, "dax=never"},
        {Opt_stripe, "stripe=%u"},
        {Opt_delalloc, "delalloc"},
        {Opt_warn_on_error, "warn_on_error"},
@@ -1729,6 +1730,7 @@ static int clear_qf_name(struct super_block *sb, int qtype)
 #define MOPT_NO_EXT3   0x0200
 #define MOPT_EXT4_ONLY (MOPT_NO_EXT2 | MOPT_NO_EXT3)
 #define MOPT_STRING    0x0400
+#define MOPT_SKIP      0x0800
 
 static const struct mount_opts {
        int     token;
@@ -1778,7 +1780,13 @@ static const struct mount_opts {
        {Opt_min_batch_time, 0, MOPT_GTE0},
        {Opt_inode_readahead_blks, 0, MOPT_GTE0},
        {Opt_init_itable, 0, MOPT_GTE0},
-       {Opt_dax, EXT4_MOUNT_DAX, MOPT_SET},
+       {Opt_dax, EXT4_MOUNT_DAX_ALWAYS, MOPT_SET | MOPT_SKIP},
+       {Opt_dax_always, EXT4_MOUNT_DAX_ALWAYS,
+               MOPT_EXT4_ONLY | MOPT_SET | MOPT_SKIP},
+       {Opt_dax_inode, EXT4_MOUNT2_DAX_INODE,
+               MOPT_EXT4_ONLY | MOPT_SET | MOPT_SKIP},
+       {Opt_dax_never, EXT4_MOUNT2_DAX_NEVER,
+               MOPT_EXT4_ONLY | MOPT_SET | MOPT_SKIP},
        {Opt_stripe, 0, MOPT_GTE0},
        {Opt_resuid, 0, MOPT_GTE0},
        {Opt_resgid, 0, MOPT_GTE0},
@@ -2123,13 +2131,56 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
                }
                sbi->s_jquota_fmt = m->mount_opt;
 #endif
-       } else if (token == Opt_dax) {
+       } else if (token == Opt_dax || token == Opt_dax_always ||
+                  token == Opt_dax_inode || token == Opt_dax_never) {
 #ifdef CONFIG_FS_DAX
-               ext4_msg(sb, KERN_WARNING,
-               "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
-               sbi->s_mount_opt |= m->mount_opt;
+               switch (token) {
+               case Opt_dax:
+               case Opt_dax_always:
+                       if (is_remount &&
+                           (!(sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS) ||
+                            (sbi->s_mount_opt2 & EXT4_MOUNT2_DAX_NEVER))) {
+                       fail_dax_change_remount:
+                               ext4_msg(sb, KERN_ERR, "can't change "
+                                        "dax mount option while remounting");
+                               return -1;
+                       }
+                       if (is_remount &&
+                           (test_opt(sb, DATA_FLAGS) ==
+                            EXT4_MOUNT_JOURNAL_DATA)) {
+                                   ext4_msg(sb, KERN_ERR, "can't mount with "
+                                            "both data=journal and dax");
+                                   return -1;
+                       }
+                       ext4_msg(sb, KERN_WARNING,
+                               "DAX enabled. Warning: EXPERIMENTAL, use at your own risk");
+                       sbi->s_mount_opt |= EXT4_MOUNT_DAX_ALWAYS;
+                       sbi->s_mount_opt2 &= ~EXT4_MOUNT2_DAX_NEVER;
+                       break;
+               case Opt_dax_never:
+                       if (is_remount &&
+                           (!(sbi->s_mount_opt2 & EXT4_MOUNT2_DAX_NEVER) ||
+                            (sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS)))
+                               goto fail_dax_change_remount;
+                       sbi->s_mount_opt2 |= EXT4_MOUNT2_DAX_NEVER;
+                       sbi->s_mount_opt &= ~EXT4_MOUNT_DAX_ALWAYS;
+                       break;
+               case Opt_dax_inode:
+                       if (is_remount &&
+                           ((sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS) ||
+                            (sbi->s_mount_opt2 & EXT4_MOUNT2_DAX_NEVER) ||
+                            !(sbi->s_mount_opt2 & EXT4_MOUNT2_DAX_INODE)))
+                               goto fail_dax_change_remount;
+                       sbi->s_mount_opt &= ~EXT4_MOUNT_DAX_ALWAYS;
+                       sbi->s_mount_opt2 &= ~EXT4_MOUNT2_DAX_NEVER;
+                       /* Strictly for printing options */
+                       sbi->s_mount_opt2 |= EXT4_MOUNT2_DAX_INODE;
+                       break;
+               }
 #else
                ext4_msg(sb, KERN_INFO, "dax option not supported");
+               sbi->s_mount_opt2 |= EXT4_MOUNT2_DAX_NEVER;
+               sbi->s_mount_opt &= ~EXT4_MOUNT_DAX_ALWAYS;
                return -1;
 #endif
        } else if (token == Opt_data_err_abort) {
@@ -2293,7 +2344,7 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
        for (m = ext4_mount_opts; m->token != Opt_err; m++) {
                int want_set = m->flags & MOPT_SET;
                if (((m->flags & (MOPT_SET|MOPT_CLEAR)) == 0) ||
-                   (m->flags & MOPT_CLEAR_ERR))
+                   (m->flags & MOPT_CLEAR_ERR) || m->flags & MOPT_SKIP)
                        continue;
                if (!nodefs && !(m->mount_opt & (sbi->s_mount_opt ^ def_mount_opt)))
                        continue; /* skip if same as the default */
@@ -2353,6 +2404,17 @@ static int _ext4_show_options(struct seq_file *seq, struct super_block *sb,
 
        fscrypt_show_test_dummy_encryption(seq, sep, sb);
 
+       if (test_opt(sb, DAX_ALWAYS)) {
+               if (IS_EXT2_SB(sb))
+                       SEQ_OPTS_PUTS("dax");
+               else
+                       SEQ_OPTS_PUTS("dax=always");
+       } else if (test_opt2(sb, DAX_NEVER)) {
+               SEQ_OPTS_PUTS("dax=never");
+       } else if (test_opt2(sb, DAX_INODE)) {
+               SEQ_OPTS_PUTS("dax=inode");
+       }
+
        ext4_show_quota_options(seq, sb);
        return 0;
 }
@@ -2383,6 +2445,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
                ext4_msg(sb, KERN_ERR, "revision level too high, "
                         "forcing read-only mode");
                err = -EROFS;
+               goto done;
        }
        if (read_only)
                goto done;
@@ -4017,7 +4080,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                                 "both data=journal and delalloc");
                        goto failed_mount;
                }
-               if (test_opt(sb, DAX)) {
+               if (test_opt(sb, DAX_ALWAYS)) {
                        ext4_msg(sb, KERN_ERR, "can't mount with "
                                 "both data=journal and dax");
                        goto failed_mount;
@@ -4127,13 +4190,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                goto failed_mount;
        }
 
-       if (sbi->s_mount_opt & EXT4_MOUNT_DAX) {
+       if (bdev_dax_supported(sb->s_bdev, blocksize))
+               set_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags);
+
+       if (sbi->s_mount_opt & EXT4_MOUNT_DAX_ALWAYS) {
                if (ext4_has_feature_inline_data(sb)) {
                        ext4_msg(sb, KERN_ERR, "Cannot use DAX on a filesystem"
                                        " that may contain inline data");
                        goto failed_mount;
                }
-               if (!bdev_dax_supported(sb->s_bdev, blocksize)) {
+               if (!test_bit(EXT4_FLAGS_BDEV_IS_DAX, &sbi->s_ext4_flags)) {
                        ext4_msg(sb, KERN_ERR,
                                "DAX unsupported by block device.");
                        goto failed_mount;
@@ -5447,12 +5513,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                        err = -EINVAL;
                        goto restore_opts;
                }
-               if (test_opt(sb, DAX)) {
-                       ext4_msg(sb, KERN_ERR, "can't mount with "
-                                "both data=journal and dax");
-                       err = -EINVAL;
-                       goto restore_opts;
-               }
        } else if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA) {
                if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
                        ext4_msg(sb, KERN_ERR, "can't mount with "
@@ -5468,12 +5528,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
                goto restore_opts;
        }
 
-       if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT4_MOUNT_DAX) {
-               ext4_msg(sb, KERN_WARNING, "warning: refusing change of "
-                       "dax flag with busy inodes while remounting");
-               sbi->s_mount_opt ^= EXT4_MOUNT_DAX;
-       }
-
        if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED)
                ext4_abort(sb, EXT4_ERR_ESHUTDOWN, "Abort forced by user");
 
index dec1244..bbd5e7e 100644 (file)
@@ -113,6 +113,9 @@ static int ext4_begin_enable_verity(struct file *filp)
        handle_t *handle;
        int err;
 
+       if (IS_DAX(inode) || ext4_test_inode_flag(inode, EXT4_INODE_DAX))
+               return -EINVAL;
+
        if (ext4_verity_in_progress(inode))
                return -EBUSY;
 
@@ -241,7 +244,7 @@ static int ext4_end_enable_verity(struct file *filp, const void *desc,
                if (err)
                        goto out_stop;
                ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
-               ext4_set_inode_flags(inode);
+               ext4_set_inode_flags(inode, false);
                err = ext4_mark_iloc_dirty(handle, inode, &iloc);
        }
 out_stop:
index 9b29a40..7d2f657 100644 (file)
@@ -93,6 +93,7 @@ static const struct xattr_handler * const ext4_xattr_handler_map[] = {
 #ifdef CONFIG_EXT4_FS_SECURITY
        [EXT4_XATTR_INDEX_SECURITY]          = &ext4_xattr_security_handler,
 #endif
+       [EXT4_XATTR_INDEX_HURD]              = &ext4_xattr_hurd_handler,
 };
 
 const struct xattr_handler *ext4_xattr_handlers[] = {
@@ -105,6 +106,7 @@ const struct xattr_handler *ext4_xattr_handlers[] = {
 #ifdef CONFIG_EXT4_FS_SECURITY
        &ext4_xattr_security_handler,
 #endif
+       &ext4_xattr_hurd_handler,
        NULL
 };
 
index ffe21ac..730b91f 100644 (file)
@@ -124,6 +124,7 @@ struct ext4_xattr_inode_array {
 extern const struct xattr_handler ext4_xattr_user_handler;
 extern const struct xattr_handler ext4_xattr_trusted_handler;
 extern const struct xattr_handler ext4_xattr_security_handler;
+extern const struct xattr_handler ext4_xattr_hurd_handler;
 
 #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c"
 
diff --git a/fs/ext4/xattr_hurd.c b/fs/ext4/xattr_hurd.c
new file mode 100644 (file)
index 0000000..8cfa74a
--- /dev/null
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/fs/ext4/xattr_hurd.c
+ * Handler for extended gnu attributes for the Hurd.
+ *
+ * Copyright (C) 2001 by Andreas Gruenbacher, <a.gruenbacher@computer.org>
+ * Copyright (C) 2020 by Jan (janneke) Nieuwenhuizen, <janneke@gnu.org>
+ */
+
+#include <linux/init.h>
+#include <linux/string.h>
+#include "ext4.h"
+#include "xattr.h"
+
+static bool
+ext4_xattr_hurd_list(struct dentry *dentry)
+{
+       return test_opt(dentry->d_sb, XATTR_USER);
+}
+
+static int
+ext4_xattr_hurd_get(const struct xattr_handler *handler,
+                   struct dentry *unused, struct inode *inode,
+                   const char *name, void *buffer, size_t size)
+{
+       if (!test_opt(inode->i_sb, XATTR_USER))
+               return -EOPNOTSUPP;
+
+       return ext4_xattr_get(inode, EXT4_XATTR_INDEX_HURD,
+                             name, buffer, size);
+}
+
+static int
+ext4_xattr_hurd_set(const struct xattr_handler *handler,
+                   struct dentry *unused, struct inode *inode,
+                   const char *name, const void *value,
+                   size_t size, int flags)
+{
+       if (!test_opt(inode->i_sb, XATTR_USER))
+               return -EOPNOTSUPP;
+
+       return ext4_xattr_set(inode, EXT4_XATTR_INDEX_HURD,
+                             name, value, size, flags);
+}
+
+const struct xattr_handler ext4_xattr_hurd_handler = {
+       .prefix = XATTR_HURD_PREFIX,
+       .list   = ext4_xattr_hurd_list,
+       .get    = ext4_xattr_hurd_get,
+       .set    = ext4_xattr_hurd_set,
+};
index 0b65a91..47c5f3a 100644 (file)
@@ -903,13 +903,15 @@ void io_wq_cancel_all(struct io_wq *wq)
 struct io_cb_cancel_data {
        work_cancel_fn *fn;
        void *data;
+       int nr_running;
+       int nr_pending;
+       bool cancel_all;
 };
 
 static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
 {
        struct io_cb_cancel_data *match = data;
        unsigned long flags;
-       bool ret = false;
 
        /*
         * Hold the lock to avoid ->cur_work going out of scope, caller
@@ -920,74 +922,90 @@ static bool io_wq_worker_cancel(struct io_worker *worker, void *data)
            !(worker->cur_work->flags & IO_WQ_WORK_NO_CANCEL) &&
            match->fn(worker->cur_work, match->data)) {
                send_sig(SIGINT, worker->task, 1);
-               ret = true;
+               match->nr_running++;
        }
        spin_unlock_irqrestore(&worker->lock, flags);
 
-       return ret;
+       return match->nr_running && !match->cancel_all;
 }
 
-static enum io_wq_cancel io_wqe_cancel_work(struct io_wqe *wqe,
-                                           struct io_cb_cancel_data *match)
+static void io_wqe_cancel_pending_work(struct io_wqe *wqe,
+                                      struct io_cb_cancel_data *match)
 {
        struct io_wq_work_node *node, *prev;
        struct io_wq_work *work;
        unsigned long flags;
-       bool found = false;
 
-       /*
-        * First check pending list, if we're lucky we can just remove it
-        * from there. CANCEL_OK means that the work is returned as-new,
-        * no completion will be posted for it.
-        */
+retry:
        spin_lock_irqsave(&wqe->lock, flags);
        wq_list_for_each(node, prev, &wqe->work_list) {
                work = container_of(node, struct io_wq_work, list);
+               if (!match->fn(work, match->data))
+                       continue;
 
-               if (match->fn(work, match->data)) {
-                       wq_list_del(&wqe->work_list, node, prev);
-                       found = true;
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&wqe->lock, flags);
-
-       if (found) {
+               wq_list_del(&wqe->work_list, node, prev);
+               spin_unlock_irqrestore(&wqe->lock, flags);
                io_run_cancel(work, wqe);
-               return IO_WQ_CANCEL_OK;
+               match->nr_pending++;
+               if (!match->cancel_all)
+                       return;
+
+               /* not safe to continue after unlock */
+               goto retry;
        }
+       spin_unlock_irqrestore(&wqe->lock, flags);
+}
 
-       /*
-        * Now check if a free (going busy) or busy worker has the work
-        * currently running. If we find it there, we'll return CANCEL_RUNNING
-        * as an indication that we attempt to signal cancellation. The
-        * completion will run normally in this case.
-        */
+static void io_wqe_cancel_running_work(struct io_wqe *wqe,
+                                      struct io_cb_cancel_data *match)
+{
        rcu_read_lock();
-       found = io_wq_for_each_worker(wqe, io_wq_worker_cancel, match);
+       io_wq_for_each_worker(wqe, io_wq_worker_cancel, match);
        rcu_read_unlock();
-       return found ? IO_WQ_CANCEL_RUNNING : IO_WQ_CANCEL_NOTFOUND;
 }
 
 enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
-                                 void *data)
+                                 void *data, bool cancel_all)
 {
        struct io_cb_cancel_data match = {
-               .fn     = cancel,
-               .data   = data,
+               .fn             = cancel,
+               .data           = data,
+               .cancel_all     = cancel_all,
        };
-       enum io_wq_cancel ret = IO_WQ_CANCEL_NOTFOUND;
        int node;
 
+       /*
+        * First check pending list, if we're lucky we can just remove it
+        * from there. CANCEL_OK means that the work is returned as-new,
+        * no completion will be posted for it.
+        */
        for_each_node(node) {
                struct io_wqe *wqe = wq->wqes[node];
 
-               ret = io_wqe_cancel_work(wqe, &match);
-               if (ret != IO_WQ_CANCEL_NOTFOUND)
-                       break;
+               io_wqe_cancel_pending_work(wqe, &match);
+               if (match.nr_pending && !match.cancel_all)
+                       return IO_WQ_CANCEL_OK;
        }
 
-       return ret;
+       /*
+        * Now check if a free (going busy) or busy worker has the work
+        * currently running. If we find it there, we'll return CANCEL_RUNNING
+        * as an indication that we attempt to signal cancellation. The
+        * completion will run normally in this case.
+        */
+       for_each_node(node) {
+               struct io_wqe *wqe = wq->wqes[node];
+
+               io_wqe_cancel_running_work(wqe, &match);
+               if (match.nr_running && !match.cancel_all)
+                       return IO_WQ_CANCEL_RUNNING;
+       }
+
+       if (match.nr_running)
+               return IO_WQ_CANCEL_RUNNING;
+       if (match.nr_pending)
+               return IO_WQ_CANCEL_OK;
+       return IO_WQ_CANCEL_NOTFOUND;
 }
 
 static bool io_wq_io_cb_cancel_data(struct io_wq_work *work, void *data)
@@ -997,21 +1015,7 @@ static bool io_wq_io_cb_cancel_data(struct io_wq_work *work, void *data)
 
 enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork)
 {
-       return io_wq_cancel_cb(wq, io_wq_io_cb_cancel_data, (void *)cwork);
-}
-
-static bool io_wq_pid_match(struct io_wq_work *work, void *data)
-{
-       pid_t pid = (pid_t) (unsigned long) data;
-
-       return work->task_pid == pid;
-}
-
-enum io_wq_cancel io_wq_cancel_pid(struct io_wq *wq, pid_t pid)
-{
-       void *data = (void *) (unsigned long) pid;
-
-       return io_wq_cancel_cb(wq, io_wq_pid_match, data);
+       return io_wq_cancel_cb(wq, io_wq_io_cb_cancel_data, (void *)cwork, false);
 }
 
 struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
index 8e138fa..071f1a9 100644 (file)
@@ -90,7 +90,6 @@ struct io_wq_work {
        const struct cred *creds;
        struct fs_struct *fs;
        unsigned flags;
-       pid_t task_pid;
 };
 
 static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
@@ -125,12 +124,11 @@ static inline bool io_wq_is_hashed(struct io_wq_work *work)
 
 void io_wq_cancel_all(struct io_wq *wq);
 enum io_wq_cancel io_wq_cancel_work(struct io_wq *wq, struct io_wq_work *cwork);
-enum io_wq_cancel io_wq_cancel_pid(struct io_wq *wq, pid_t pid);
 
 typedef bool (work_cancel_fn)(struct io_wq_work *, void *);
 
 enum io_wq_cancel io_wq_cancel_cb(struct io_wq *wq, work_cancel_fn *cancel,
-                                       void *data);
+                                       void *data, bool cancel_all);
 
 struct task_struct *io_wq_get_task(struct io_wq *wq);
 
index 155f3d8..a78201b 100644 (file)
@@ -541,6 +541,7 @@ enum {
        REQ_F_NO_FILE_TABLE_BIT,
        REQ_F_QUEUE_TIMEOUT_BIT,
        REQ_F_WORK_INITIALIZED_BIT,
+       REQ_F_TASK_PINNED_BIT,
 
        /* not a real bit, just to check we're not overflowing the space */
        __REQ_F_LAST_BIT,
@@ -598,6 +599,8 @@ enum {
        REQ_F_QUEUE_TIMEOUT     = BIT(REQ_F_QUEUE_TIMEOUT_BIT),
        /* io_wq_work is initialized */
        REQ_F_WORK_INITIALIZED  = BIT(REQ_F_WORK_INITIALIZED_BIT),
+       /* req->task is refcounted */
+       REQ_F_TASK_PINNED       = BIT(REQ_F_TASK_PINNED_BIT),
 };
 
 struct async_poll {
@@ -910,6 +913,21 @@ struct sock *io_uring_get_socket(struct file *file)
 }
 EXPORT_SYMBOL(io_uring_get_socket);
 
+static void io_get_req_task(struct io_kiocb *req)
+{
+       if (req->flags & REQ_F_TASK_PINNED)
+               return;
+       get_task_struct(req->task);
+       req->flags |= REQ_F_TASK_PINNED;
+}
+
+/* not idempotent -- it doesn't clear REQ_F_TASK_PINNED */
+static void __io_put_req_task(struct io_kiocb *req)
+{
+       if (req->flags & REQ_F_TASK_PINNED)
+               put_task_struct(req->task);
+}
+
 static void io_file_put_work(struct work_struct *work);
 
 /*
@@ -1045,8 +1063,6 @@ static inline void io_req_work_grab_env(struct io_kiocb *req,
                }
                spin_unlock(&current->fs->lock);
        }
-       if (!req->work.task_pid)
-               req->work.task_pid = task_pid_vnr(current);
 }
 
 static inline void io_req_work_drop_env(struct io_kiocb *req)
@@ -1087,6 +1103,7 @@ static inline void io_prep_async_work(struct io_kiocb *req,
                        req->work.flags |= IO_WQ_WORK_UNBOUND;
        }
 
+       io_req_init_async(req);
        io_req_work_grab_env(req, def);
 
        *link = io_prep_linked_timeout(req);
@@ -1398,9 +1415,7 @@ static void __io_req_aux_free(struct io_kiocb *req)
        kfree(req->io);
        if (req->file)
                io_put_file(req, req->file, (req->flags & REQ_F_FIXED_FILE));
-       if (req->task)
-               put_task_struct(req->task);
-
+       __io_put_req_task(req);
        io_req_work_drop_env(req);
 }
 
@@ -1727,6 +1742,18 @@ static int io_put_kbuf(struct io_kiocb *req)
        return cflags;
 }
 
+static void io_iopoll_queue(struct list_head *again)
+{
+       struct io_kiocb *req;
+
+       do {
+               req = list_first_entry(again, struct io_kiocb, list);
+               list_del(&req->list);
+               refcount_inc(&req->refs);
+               io_queue_async_work(req);
+       } while (!list_empty(again));
+}
+
 /*
  * Find and free completed poll iocbs
  */
@@ -1735,12 +1762,21 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events,
 {
        struct req_batch rb;
        struct io_kiocb *req;
+       LIST_HEAD(again);
+
+       /* order with ->result store in io_complete_rw_iopoll() */
+       smp_rmb();
 
        rb.to_free = rb.need_iter = 0;
        while (!list_empty(done)) {
                int cflags = 0;
 
                req = list_first_entry(done, struct io_kiocb, list);
+               if (READ_ONCE(req->result) == -EAGAIN) {
+                       req->iopoll_completed = 0;
+                       list_move_tail(&req->list, &again);
+                       continue;
+               }
                list_del(&req->list);
 
                if (req->flags & REQ_F_BUFFER_SELECTED)
@@ -1758,18 +1794,9 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events,
        if (ctx->flags & IORING_SETUP_SQPOLL)
                io_cqring_ev_posted(ctx);
        io_free_req_many(ctx, &rb);
-}
 
-static void io_iopoll_queue(struct list_head *again)
-{
-       struct io_kiocb *req;
-
-       do {
-               req = list_first_entry(again, struct io_kiocb, list);
-               list_del(&req->list);
-               refcount_inc(&req->refs);
-               io_queue_async_work(req);
-       } while (!list_empty(again));
+       if (!list_empty(&again))
+               io_iopoll_queue(&again);
 }
 
 static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
@@ -1777,7 +1804,6 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
 {
        struct io_kiocb *req, *tmp;
        LIST_HEAD(done);
-       LIST_HEAD(again);
        bool spin;
        int ret;
 
@@ -1803,13 +1829,6 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
                if (!list_empty(&done))
                        break;
 
-               if (req->result == -EAGAIN) {
-                       list_move_tail(&req->list, &again);
-                       continue;
-               }
-               if (!list_empty(&again))
-                       break;
-
                ret = kiocb->ki_filp->f_op->iopoll(kiocb, spin);
                if (ret < 0)
                        break;
@@ -1822,9 +1841,6 @@ static int io_do_iopoll(struct io_ring_ctx *ctx, unsigned int *nr_events,
        if (!list_empty(&done))
                io_iopoll_complete(ctx, nr_events, &done);
 
-       if (!list_empty(&again))
-               io_iopoll_queue(&again);
-
        return ret;
 }
 
@@ -1973,11 +1989,15 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
        if (kiocb->ki_flags & IOCB_WRITE)
                kiocb_end_write(req);
 
-       if (res != req->result)
+       if (res != -EAGAIN && res != req->result)
                req_set_fail_links(req);
-       req->result = res;
-       if (res != -EAGAIN)
+
+       WRITE_ONCE(req->result, res);
+       /* order with io_poll_complete() checking ->result */
+       if (res != -EAGAIN) {
+               smp_wmb();
                WRITE_ONCE(req->iopoll_completed, 1);
+       }
 }
 
 /*
@@ -2650,8 +2670,8 @@ copy_iov:
                }
        }
 out_free:
-       kfree(iovec);
-       req->flags &= ~REQ_F_NEED_CLEANUP;
+       if (!(req->flags & REQ_F_NEED_CLEANUP))
+               kfree(iovec);
        return ret;
 }
 
@@ -2773,8 +2793,8 @@ copy_iov:
                }
        }
 out_free:
-       req->flags &= ~REQ_F_NEED_CLEANUP;
-       kfree(iovec);
+       if (!(req->flags & REQ_F_NEED_CLEANUP))
+               kfree(iovec);
        return ret;
 }
 
@@ -4236,6 +4256,28 @@ static void io_async_queue_proc(struct file *file, struct wait_queue_head *head,
        __io_queue_proc(&pt->req->apoll->poll, pt, head);
 }
 
+static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
+{
+       struct mm_struct *mm = current->mm;
+
+       if (mm) {
+               kthread_unuse_mm(mm);
+               mmput(mm);
+       }
+}
+
+static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
+                                  struct io_kiocb *req)
+{
+       if (io_op_defs[req->opcode].needs_mm && !current->mm) {
+               if (unlikely(!mmget_not_zero(ctx->sqo_mm)))
+                       return -EFAULT;
+               kthread_use_mm(ctx->sqo_mm);
+       }
+
+       return 0;
+}
+
 static void io_async_task_func(struct callback_head *cb)
 {
        struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
@@ -4270,11 +4312,16 @@ static void io_async_task_func(struct callback_head *cb)
 
        if (!canceled) {
                __set_current_state(TASK_RUNNING);
+               if (io_sq_thread_acquire_mm(ctx, req)) {
+                       io_cqring_add_event(req, -EFAULT);
+                       goto end_req;
+               }
                mutex_lock(&ctx->uring_lock);
                __io_queue_sqe(req, NULL);
                mutex_unlock(&ctx->uring_lock);
        } else {
                io_cqring_ev_posted(ctx);
+end_req:
                req_set_fail_links(req);
                io_double_put_req(req);
        }
@@ -4366,8 +4413,7 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
                memcpy(&apoll->work, &req->work, sizeof(req->work));
        had_io = req->io != NULL;
 
-       get_task_struct(current);
-       req->task = current;
+       io_get_req_task(req);
        req->apoll = apoll;
        INIT_HLIST_NODE(&req->hash_node);
 
@@ -4555,8 +4601,7 @@ static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
        events = READ_ONCE(sqe->poll_events);
        poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP;
 
-       get_task_struct(current);
-       req->task = current;
+       io_get_req_task(req);
        return 0;
 }
 
@@ -4772,7 +4817,7 @@ static int io_async_cancel_one(struct io_ring_ctx *ctx, void *sqe_addr)
        enum io_wq_cancel cancel_ret;
        int ret = 0;
 
-       cancel_ret = io_wq_cancel_cb(ctx->io_wq, io_cancel_cb, sqe_addr);
+       cancel_ret = io_wq_cancel_cb(ctx->io_wq, io_cancel_cb, sqe_addr, false);
        switch (cancel_ret) {
        case IO_WQ_CANCEL_OK:
                ret = 0;
@@ -5817,17 +5862,14 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
        req->flags = 0;
        /* one is dropped after submission, the other at completion */
        refcount_set(&req->refs, 2);
-       req->task = NULL;
+       req->task = current;
        req->result = 0;
 
        if (unlikely(req->opcode >= IORING_OP_LAST))
                return -EINVAL;
 
-       if (io_op_defs[req->opcode].needs_mm && !current->mm) {
-               if (unlikely(!mmget_not_zero(ctx->sqo_mm)))
-                       return -EFAULT;
-               kthread_use_mm(ctx->sqo_mm);
-       }
+       if (unlikely(io_sq_thread_acquire_mm(ctx, req)))
+               return -EFAULT;
 
        sqe_flags = READ_ONCE(sqe->flags);
        /* enforce forwards compatibility on users */
@@ -5936,16 +5978,6 @@ fail_req:
        return submitted;
 }
 
-static inline void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
-{
-       struct mm_struct *mm = current->mm;
-
-       if (mm) {
-               kthread_unuse_mm(mm);
-               mmput(mm);
-       }
-}
-
 static int io_sq_thread(void *data)
 {
        struct io_ring_ctx *ctx = data;
@@ -7331,7 +7363,17 @@ static void io_ring_exit_work(struct work_struct *work)
        if (ctx->rings)
                io_cqring_overflow_flush(ctx, true);
 
-       wait_for_completion(&ctx->ref_comp);
+       /*
+        * If we're doing polled IO and end up having requests being
+        * submitted async (out-of-line), then completions can come in while
+        * we're waiting for refs to drop. We need to reap these manually,
+        * as nobody else will be looking for them.
+        */
+       while (!wait_for_completion_timeout(&ctx->ref_comp, HZ/20)) {
+               io_iopoll_reap_events(ctx);
+               if (ctx->rings)
+                       io_cqring_overflow_flush(ctx, true);
+       }
        io_ring_ctx_free(ctx);
 }
 
@@ -7365,9 +7407,22 @@ static int io_uring_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+static bool io_wq_files_match(struct io_wq_work *work, void *data)
+{
+       struct files_struct *files = data;
+
+       return work->files == files;
+}
+
 static void io_uring_cancel_files(struct io_ring_ctx *ctx,
                                  struct files_struct *files)
 {
+       if (list_empty_careful(&ctx->inflight_list))
+               return;
+
+       /* cancel all at once, should be faster than doing it one by one*/
+       io_wq_cancel_cb(ctx->io_wq, io_wq_files_match, files, true);
+
        while (!list_empty_careful(&ctx->inflight_list)) {
                struct io_kiocb *cancel_req = NULL, *req;
                DEFINE_WAIT(wait);
@@ -7423,6 +7478,14 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
        }
 }
 
+static bool io_cancel_task_cb(struct io_wq_work *work, void *data)
+{
+       struct io_kiocb *req = container_of(work, struct io_kiocb, work);
+       struct task_struct *task = data;
+
+       return req->task == task;
+}
+
 static int io_uring_flush(struct file *file, void *data)
 {
        struct io_ring_ctx *ctx = file->private_data;
@@ -7433,7 +7496,7 @@ static int io_uring_flush(struct file *file, void *data)
         * If the task is going away, cancel work it may have pending
         */
        if (fatal_signal_pending(current) || (current->flags & PF_EXITING))
-               io_wq_cancel_pid(ctx->io_wq, task_pid_vnr(current));
+               io_wq_cancel_cb(ctx->io_wq, io_cancel_task_cb, current, true);
 
        return 0;
 }
index a49d0e6..e494443 100644 (file)
@@ -1140,6 +1140,7 @@ static journal_t *journal_init_common(struct block_device *bdev,
        init_waitqueue_head(&journal->j_wait_commit);
        init_waitqueue_head(&journal->j_wait_updates);
        init_waitqueue_head(&journal->j_wait_reserved);
+       mutex_init(&journal->j_abort_mutex);
        mutex_init(&journal->j_barrier);
        mutex_init(&journal->j_checkpoint_mutex);
        spin_lock_init(&journal->j_revoke_lock);
@@ -1402,7 +1403,8 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
                printk(KERN_ERR "JBD2: Error %d detected when updating "
                       "journal superblock for %s.\n", ret,
                       journal->j_devname);
-               jbd2_journal_abort(journal, ret);
+               if (!is_journal_aborted(journal))
+                       jbd2_journal_abort(journal, ret);
        }
 
        return ret;
@@ -2153,6 +2155,13 @@ void jbd2_journal_abort(journal_t *journal, int errno)
 {
        transaction_t *transaction;
 
+       /*
+        * Lock the aborting procedure until everything is done, this avoid
+        * races between filesystem's error handling flow (e.g. ext4_abort()),
+        * ensure panic after the error info is written into journal's
+        * superblock.
+        */
+       mutex_lock(&journal->j_abort_mutex);
        /*
         * ESHUTDOWN always takes precedence because a file system check
         * caused by any other journal abort error is not required after
@@ -2167,6 +2176,7 @@ void jbd2_journal_abort(journal_t *journal, int errno)
                        journal->j_errno = errno;
                        jbd2_journal_update_sb_errno(journal);
                }
+               mutex_unlock(&journal->j_abort_mutex);
                return;
        }
 
@@ -2188,10 +2198,7 @@ void jbd2_journal_abort(journal_t *journal, int errno)
         * layer could realise that a filesystem check is needed.
         */
        jbd2_journal_update_sb_errno(journal);
-
-       write_lock(&journal->j_state_lock);
-       journal->j_flags |= JBD2_REC_ERR;
-       write_unlock(&journal->j_state_lock);
+       mutex_unlock(&journal->j_abort_mutex);
 }
 
 /**
index 0637271..8ff4d1a 100644 (file)
@@ -259,7 +259,7 @@ struct jffs2_full_dirent
        uint32_t ino; /* == zero for unlink */
        unsigned int nhash;
        unsigned char type;
-       unsigned char name[0];
+       unsigned char name[];
 };
 
 /*
index 60207a2..e4131cb 100644 (file)
@@ -61,7 +61,7 @@ struct jffs2_sum_dirent_flash
        jint32_t ino;           /* == zero for unlink */
        uint8_t nsize;          /* dirent name size */
        uint8_t type;           /* dirent type */
-       uint8_t name[0];        /* dirent name */
+       uint8_t name[]; /* dirent name */
 } __attribute__((packed));
 
 struct jffs2_sum_xattr_flash
@@ -117,7 +117,7 @@ struct jffs2_sum_dirent_mem
        jint32_t ino;           /* == zero for unlink */
        uint8_t nsize;          /* dirent name size */
        uint8_t type;           /* dirent type */
-       uint8_t name[0];        /* dirent name */
+       uint8_t name[]; /* dirent name */
 } __attribute__((packed));
 
 struct jffs2_sum_xattr_mem
index 9955d75..ad31ec4 100644 (file)
@@ -26,8 +26,9 @@ static int boot_config_proc_show(struct seq_file *m, void *v)
 static int __init copy_xbc_key_value_list(char *dst, size_t size)
 {
        struct xbc_node *leaf, *vnode;
-       const char *val;
        char *key, *end = dst + size;
+       const char *val;
+       char q;
        int ret = 0;
 
        key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL);
@@ -41,16 +42,20 @@ static int __init copy_xbc_key_value_list(char *dst, size_t size)
                        break;
                dst += ret;
                vnode = xbc_node_get_child(leaf);
-               if (vnode && xbc_node_is_array(vnode)) {
+               if (vnode) {
                        xbc_array_for_each_value(vnode, val) {
-                               ret = snprintf(dst, rest(dst, end), "\"%s\"%s",
-                                       val, vnode->next ? ", " : "\n");
+                               if (strchr(val, '"'))
+                                       q = '\'';
+                               else
+                                       q = '"';
+                               ret = snprintf(dst, rest(dst, end), "%c%s%c%s",
+                                       q, val, q, vnode->next ? ", " : "\n");
                                if (ret < 0)
                                        goto out;
                                dst += ret;
                        }
                } else {
-                       ret = snprintf(dst, rest(dst, end), "\"%s\"\n", val);
+                       ret = snprintf(dst, rest(dst, end), "\"\"\n");
                        if (ret < 0)
                                break;
                        dst += ret;
index 8ba492d..e502414 100644 (file)
@@ -512,7 +512,8 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                                 * Using bounce buffer to bypass the
                                 * hardened user copy kernel text checks.
                                 */
-                               if (probe_kernel_read(buf, (void *) start, tsz)) {
+                               if (copy_from_kernel_nofault(buf, (void *)start,
+                                               tsz)) {
                                        if (clear_user(buffer, tsz)) {
                                                ret = -EFAULT;
                                                goto out;
index 7187bd1..8d64edb 100644 (file)
@@ -262,7 +262,7 @@ struct squashfs_dir_index {
        __le32                  index;
        __le32                  start_block;
        __le32                  size;
-       unsigned char           name[0];
+       unsigned char           name[];
 };
 
 struct squashfs_base_inode {
@@ -327,7 +327,7 @@ struct squashfs_symlink_inode {
        __le32                  inode_number;
        __le32                  nlink;
        __le32                  symlink_size;
-       char                    symlink[0];
+       char                    symlink[];
 };
 
 struct squashfs_reg_inode {
@@ -341,7 +341,7 @@ struct squashfs_reg_inode {
        __le32                  fragment;
        __le32                  offset;
        __le32                  file_size;
-       __le16                  block_list[0];
+       __le16                  block_list[];
 };
 
 struct squashfs_lreg_inode {
@@ -358,7 +358,7 @@ struct squashfs_lreg_inode {
        __le32                  fragment;
        __le32                  offset;
        __le32                  xattr;
-       __le16                  block_list[0];
+       __le16                  block_list[];
 };
 
 struct squashfs_dir_inode {
@@ -389,7 +389,7 @@ struct squashfs_ldir_inode {
        __le16                  i_count;
        __le16                  offset;
        __le32                  xattr;
-       struct squashfs_dir_index       index[0];
+       struct squashfs_dir_index       index[];
 };
 
 union squashfs_inode {
@@ -410,7 +410,7 @@ struct squashfs_dir_entry {
        __le16                  inode_number;
        __le16                  type;
        __le16                  size;
-       char                    name[0];
+       char                    name[];
 };
 
 struct squashfs_dir_header {
@@ -428,12 +428,12 @@ struct squashfs_fragment_entry {
 struct squashfs_xattr_entry {
        __le16                  type;
        __le16                  size;
-       char                    data[0];
+       char                    data[];
 };
 
 struct squashfs_xattr_val {
        __le32                  vsize;
-       char                    value[0];
+       char                    value[];
 };
 
 struct squashfs_xattr_id {
index 40f85de..8e1e624 100644 (file)
@@ -122,7 +122,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 #ifndef __HAVE_ARCH_HUGE_PTEP_GET
 static inline pte_t huge_ptep_get(pte_t *ptep)
 {
-       return READ_ONCE(*ptep);
+       return ptep_get(ptep);
 }
 #endif
 
index 27bdd27..77941ef 100644 (file)
@@ -89,7 +89,7 @@ struct displayid_detailed_timings_1 {
 
 struct displayid_detailed_timing_block {
        struct displayid_block base;
-       struct displayid_detailed_timings_1 timings[0];
+       struct displayid_detailed_timings_1 timings[];
 };
 
 #define for_each_displayid_db(displayid, block, idx, length) \
index 9e9ccb2..38afb34 100644 (file)
@@ -27,7 +27,7 @@ struct encrypted_key_payload {
        unsigned short payload_datalen;         /* payload data length */
        unsigned short encrypted_key_format;    /* encrypted key format */
        u8 *decrypted_data;     /* decrypted data */
-       u8 payload_data[0];     /* payload data + datablob + hmac */
+       u8 payload_data[];      /* payload data + datablob + hmac */
 };
 
 extern struct key_type key_type_encrypted;
index a183278..2b0b15a 100644 (file)
@@ -28,7 +28,7 @@ struct rxkad_key {
        u8      primary_flag;           /* T if key for primary cell for this user */
        u16     ticket_len;             /* length of ticket[] */
        u8      session_key[8];         /* DES session key */
-       u8      ticket[0];              /* the encrypted ticket */
+       u8      ticket[];               /* the encrypted ticket */
 };
 
 /*
@@ -100,7 +100,7 @@ struct rxrpc_key_data_v1 {
        u32             expiry;                 /* time_t */
        u32             kvno;
        u8              session_key[8];
-       u8              ticket[0];
+       u8              ticket[];
 };
 
 /*
index a954def..900b9f4 100644 (file)
@@ -34,7 +34,7 @@
 struct can_skb_priv {
        int ifindex;
        int skbcnt;
-       struct can_frame cf[0];
+       struct can_frame cf[];
 };
 
 static inline struct can_skb_priv *can_skb_prv(struct sk_buff *skb)
index 60de3fe..405657a 100644 (file)
@@ -36,7 +36,7 @@ struct cb710_chip {
        unsigned                slot_mask;
        unsigned                slots;
        spinlock_t              irq_lock;
-       struct cb710_slot       slot[0];
+       struct cb710_slot       slot[];
 };
 
 /* NOTE: cb710_chip.slots is modified only during device init/exit and
index 2247e71..e5ed1c5 100644 (file)
@@ -52,8 +52,7 @@ struct ceph_options {
        unsigned long osd_idle_ttl;             /* jiffies */
        unsigned long osd_keepalive_timeout;    /* jiffies */
        unsigned long osd_request_timeout;      /* jiffies */
-
-       u32 osd_req_flags;  /* CEPH_OSD_FLAG_*, applied to each OSD request */
+       u32 read_from_replica;  /* CEPH_OSD_FLAG_BALANCE/LOCALIZE_READS */
 
        /*
         * any type that can't be simply compared or doesn't need
@@ -76,6 +75,7 @@ struct ceph_options {
 #define CEPH_OSD_KEEPALIVE_DEFAULT     msecs_to_jiffies(5 * 1000)
 #define CEPH_OSD_IDLE_TTL_DEFAULT      msecs_to_jiffies(60 * 1000)
 #define CEPH_OSD_REQUEST_TIMEOUT_DEFAULT 0  /* no timeout */
+#define CEPH_READ_FROM_REPLICA_DEFAULT 0  /* read from primary */
 
 #define CEPH_MONC_HUNT_INTERVAL                msecs_to_jiffies(3 * 1000)
 #define CEPH_MONC_PING_INTERVAL                msecs_to_jiffies(10 * 1000)
index 21aed09..e368384 100644 (file)
@@ -5,20 +5,20 @@
 #ifndef __ASSEMBLY__
 
 #ifdef __CHECKER__
-# define __user                __attribute__((noderef, address_space(1)))
 # define __kernel      __attribute__((address_space(0)))
+# define __user                __attribute__((noderef, address_space(__user)))
 # define __safe                __attribute__((safe))
 # define __force       __attribute__((force))
 # define __nocast      __attribute__((nocast))
-# define __iomem       __attribute__((noderef, address_space(2)))
+# define __iomem       __attribute__((noderef, address_space(__iomem)))
 # define __must_hold(x)        __attribute__((context(x,1,1)))
 # define __acquires(x) __attribute__((context(x,0,1)))
 # define __releases(x) __attribute__((context(x,1,0)))
 # define __acquire(x)  __context__(x,1)
 # define __release(x)  __context__(x,-1)
 # define __cond_lock(x,c)      ((c) ? ({ __acquire(x); 1; }) : 0)
-# define __percpu      __attribute__((noderef, address_space(3)))
-# define __rcu         __attribute__((noderef, address_space(4)))
+# define __percpu      __attribute__((noderef, address_space(__percpu)))
+# define __rcu         __attribute__((noderef, address_space(__rcu)))
 # define __private     __attribute__((noderef))
 extern void __chk_user_ptr(const volatile void __user *);
 extern void __chk_io_ptr(const volatile void __iomem *);
index e1c0333..6283917 100644 (file)
@@ -153,7 +153,7 @@ struct dma_interleaved_template {
        bool dst_sgl;
        size_t numf;
        size_t frame_size;
-       struct data_chunk sgl[0];
+       struct data_chunk sgl[];
 };
 
 /**
@@ -535,7 +535,7 @@ struct dmaengine_unmap_data {
        struct device *dev;
        struct kref kref;
        size_t len;
-       dma_addr_t addr[0];
+       dma_addr_t addr[];
 };
 
 struct dma_async_tx_descriptor;
index 6c4ab4d..3f881a8 100644 (file)
@@ -2592,7 +2592,6 @@ extern void bdput(struct block_device *);
 extern void invalidate_bdev(struct block_device *);
 extern void iterate_bdevs(void (*)(struct block_device *, void *), void *);
 extern int sync_blockdev(struct block_device *bdev);
-extern void kill_bdev(struct block_device *);
 extern struct super_block *freeze_bdev(struct block_device *);
 extern void emergency_thaw_all(void);
 extern void emergency_thaw_bdev(struct super_block *sb);
@@ -2608,7 +2607,6 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
 #else
 static inline void bd_forget(struct inode *inode) {}
 static inline int sync_blockdev(struct block_device *bdev) { return 0; }
-static inline void kill_bdev(struct block_device *bdev) {}
 static inline void invalidate_bdev(struct block_device *bdev) {}
 
 static inline struct super_block *freeze_bdev(struct block_device *sb)
index ce0b5fb..3f0b19d 100644 (file)
@@ -46,7 +46,7 @@ struct fscache_cache_tag {
        unsigned long           flags;
 #define FSCACHE_TAG_RESERVED   0               /* T if tag is reserved for a cache */
        atomic_t                usage;
-       char                    name[0];        /* tag name */
+       char                    name[]; /* tag name */
 };
 
 /*
index c10617b..b8b8963 100644 (file)
@@ -408,7 +408,7 @@ static inline bool i2c_detect_slave_mode(struct device *dev) { return false; }
  * that are present.  This information is used to grow the driver model tree.
  * For mainboards this is done statically using i2c_register_board_info();
  * bus numbers identify adapters that aren't yet available.  For add-on boards,
- * i2c_new_device() does this dynamically with the adapter already known.
+ * i2c_new_client_device() does this dynamically with the adapter already known.
  */
 struct i2c_board_info {
        char            type[I2C_NAME_SIZE];
@@ -439,13 +439,11 @@ struct i2c_board_info {
 
 
 #if IS_ENABLED(CONFIG_I2C)
-/* Add-on boards should register/unregister their devices; e.g. a board
+/*
+ * Add-on boards should register/unregister their devices; e.g. a board
  * with integrated I2C, a config eeprom, sensors, and a codec that's
  * used in conjunction with the primary hardware.
  */
-struct i2c_client *
-i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
-
 struct i2c_client *
 i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
 
index f613d85..d56128d 100644 (file)
@@ -765,6 +765,11 @@ struct journal_s
         */
        int                     j_errno;
 
+       /**
+        * @j_abort_mutex: Lock the whole aborting procedure.
+        */
+       struct mutex            j_abort_mutex;
+
        /**
         * @j_sb_buffer: The first part of the superblock buffer.
         */
@@ -1247,7 +1252,6 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3,                CSUM_V3)
 #define JBD2_ABORT_ON_SYNCDATA_ERR     0x040   /* Abort the journal on file
                                                 * data write error in ordered
                                                 * mode */
-#define JBD2_REC_ERR   0x080   /* The errno in the sb has been recorded */
 
 /*
  * Function declarations for the journaling transaction and buffer
index 1776eb2..ea67910 100644 (file)
@@ -208,7 +208,7 @@ struct crash_mem_range {
 struct crash_mem {
        unsigned int max_nr_ranges;
        unsigned int nr_ranges;
-       struct crash_mem_range ranges[0];
+       struct crash_mem_range ranges[];
 };
 
 extern int crash_exclude_mem_range(struct crash_mem *mem,
index 594265b..6adf90f 100644 (file)
@@ -161,7 +161,7 @@ struct kretprobe_instance {
        kprobe_opcode_t *ret_addr;
        struct task_struct *task;
        void *fp;
-       char data[0];
+       char data[];
 };
 
 struct kretprobe_blackpoint {
@@ -350,6 +350,10 @@ static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
        return this_cpu_ptr(&kprobe_ctlblk);
 }
 
+extern struct kprobe kprobe_busy;
+void kprobe_busy_begin(void);
+void kprobe_busy_end(void);
+
 kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset);
 int register_kprobe(struct kprobe *p);
 void unregister_kprobe(struct kprobe *p);
index 62ec926..d564855 100644 (file)
@@ -409,7 +409,7 @@ struct kvm_irq_routing_table {
         * Array indexed by gsi. Each entry contains list of irq chips
         * the gsi is connected to.
         */
-       struct hlist_head map[0];
+       struct hlist_head map[];
 };
 #endif
 
index af83285..e7e5256 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/acpi.h>
 #include <linux/cdrom.h>
 #include <linux/sched.h>
+#include <linux/async.h>
 
 /*
  * Define if arch has non-standard setup.  This is a _PCI_ standard
@@ -609,7 +610,7 @@ struct ata_host {
        struct task_struct      *eh_owner;
 
        struct ata_port         *simplex_claimed;       /* channel owning the DMA */
-       struct ata_port         *ports[0];
+       struct ata_port         *ports[];
 };
 
 struct ata_queued_cmd {
@@ -872,6 +873,8 @@ struct ata_port {
        struct timer_list       fastdrain_timer;
        unsigned long           fastdrain_cnt;
 
+       async_cookie_t          cookie;
+
        int                     em_message_type;
        void                    *private_data;
 
@@ -1092,7 +1095,11 @@ extern int ata_scsi_ioctl(struct scsi_device *dev, unsigned int cmd,
 #define ATA_SCSI_COMPAT_IOCTL /* empty */
 #endif
 extern int ata_scsi_queuecmd(struct Scsi_Host *h, struct scsi_cmnd *cmd);
+#if IS_ENABLED(CONFIG_ATA)
 bool ata_scsi_dma_need_drain(struct request *rq);
+#else
+#define ata_scsi_dma_need_drain NULL
+#endif
 extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev,
                            unsigned int cmd, void __user *arg);
 extern bool ata_link_online(struct ata_link *link);
index 6590450..93fcef1 100644 (file)
@@ -304,16 +304,33 @@ static inline __must_check size_t __ab_c_size(size_t a, size_t b, size_t c)
  * struct_size() - Calculate size of structure with trailing array.
  * @p: Pointer to the structure.
  * @member: Name of the array member.
- * @n: Number of elements in the array.
+ * @count: Number of elements in the array.
  *
  * Calculates size of memory needed for structure @p followed by an
- * array of @n @member elements.
+ * array of @count number of @member elements.
  *
  * Return: number of bytes needed or SIZE_MAX on overflow.
  */
-#define struct_size(p, member, n)                                      \
-       __ab_c_size(n,                                                  \
+#define struct_size(p, member, count)                                  \
+       __ab_c_size(count,                                              \
                    sizeof(*(p)->member) + __must_be_array((p)->member),\
                    sizeof(*(p)))
 
+/**
+ * flex_array_size() - Calculate size of a flexible array member
+ *                     within an enclosing structure.
+ *
+ * @p: Pointer to the structure.
+ * @member: Name of the flexible array member.
+ * @count: Number of elements in the array.
+ *
+ * Calculates size of a flexible array of @count number of @member
+ * elements, at the end of structure @p.
+ *
+ * Return: number of bytes needed or SIZE_MAX on overflow.
+ */
+#define flex_array_size(p, member, count)                              \
+       array_size(count,                                               \
+                   sizeof(*(p)->member) + __must_be_array((p)->member))
+
 #endif /* __LINUX_OVERFLOW_H */
index 32b6c52..56c1e8e 100644 (file)
@@ -249,6 +249,13 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 }
 #endif
 
+#ifndef __HAVE_ARCH_PTEP_GET
+static inline pte_t ptep_get(pte_t *ptep)
+{
+       return READ_ONCE(*ptep);
+}
+#endif
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #ifndef __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
index 7fbc867..49d155c 100644 (file)
@@ -597,7 +597,7 @@ int sev_guest_df_flush(int *error);
  */
 int sev_guest_decommission(struct sev_data_decommission *data, int *error);
 
-void *psp_copy_user_blob(u64 __user uaddr, u32 len);
+void *psp_copy_user_blob(u64 uaddr, u32 len);
 
 #else  /* !CONFIG_CRYPTO_DEV_SP_PSP */
 
index 8ccd821..7673123 100644 (file)
@@ -221,7 +221,7 @@ struct sctp_datahdr {
        __be16 stream;
        __be16 ssn;
        __u32 ppid;
-       __u8  payload[0];
+       __u8  payload[];
 };
 
 struct sctp_data_chunk {
@@ -269,7 +269,7 @@ struct sctp_inithdr {
        __be16 num_outbound_streams;
        __be16 num_inbound_streams;
        __be32 initial_tsn;
-       __u8  params[0];
+       __u8  params[];
 };
 
 struct sctp_init_chunk {
@@ -299,13 +299,13 @@ struct sctp_cookie_preserve_param {
 /* Section 3.3.2.1 Host Name Address (11) */
 struct sctp_hostname_param {
        struct sctp_paramhdr param_hdr;
-       uint8_t hostname[0];
+       uint8_t hostname[];
 };
 
 /* Section 3.3.2.1 Supported Address Types (12) */
 struct sctp_supported_addrs_param {
        struct sctp_paramhdr param_hdr;
-       __be16 types[0];
+       __be16 types[];
 };
 
 /* ADDIP Section 3.2.6 Adaptation Layer Indication */
@@ -317,25 +317,25 @@ struct sctp_adaptation_ind_param {
 /* ADDIP Section 4.2.7 Supported Extensions Parameter */
 struct sctp_supported_ext_param {
        struct sctp_paramhdr param_hdr;
-       __u8 chunks[0];
+       __u8 chunks[];
 };
 
 /* AUTH Section 3.1 Random */
 struct sctp_random_param {
        struct sctp_paramhdr param_hdr;
-       __u8 random_val[0];
+       __u8 random_val[];
 };
 
 /* AUTH Section 3.2 Chunk List */
 struct sctp_chunks_param {
        struct sctp_paramhdr param_hdr;
-       __u8 chunks[0];
+       __u8 chunks[];
 };
 
 /* AUTH Section 3.3 HMAC Algorithm */
 struct sctp_hmac_algo_param {
        struct sctp_paramhdr param_hdr;
-       __be16 hmac_ids[0];
+       __be16 hmac_ids[];
 };
 
 /* RFC 2960.  Section 3.3.3 Initiation Acknowledgement (INIT ACK) (2):
@@ -350,7 +350,7 @@ struct sctp_initack_chunk {
 /* Section 3.3.3.1 State Cookie (7) */
 struct sctp_cookie_param {
        struct sctp_paramhdr p;
-       __u8 body[0];
+       __u8 body[];
 };
 
 /* Section 3.3.3.1 Unrecognized Parameters (8) */
@@ -384,7 +384,7 @@ struct sctp_sackhdr {
        __be32 a_rwnd;
        __be16 num_gap_ack_blocks;
        __be16 num_dup_tsns;
-       union sctp_sack_variable variable[0];
+       union sctp_sack_variable variable[];
 };
 
 struct sctp_sack_chunk {
@@ -436,7 +436,7 @@ struct sctp_shutdown_chunk {
 struct sctp_errhdr {
        __be16 cause;
        __be16 length;
-       __u8  variable[0];
+       __u8  variable[];
 };
 
 struct sctp_operr_chunk {
@@ -594,7 +594,7 @@ struct sctp_fwdtsn_skip {
 
 struct sctp_fwdtsn_hdr {
        __be32 new_cum_tsn;
-       struct sctp_fwdtsn_skip skip[0];
+       struct sctp_fwdtsn_skip skip[];
 };
 
 struct sctp_fwdtsn_chunk {
@@ -611,7 +611,7 @@ struct sctp_ifwdtsn_skip {
 
 struct sctp_ifwdtsn_hdr {
        __be32 new_cum_tsn;
-       struct sctp_ifwdtsn_skip skip[0];
+       struct sctp_ifwdtsn_skip skip[];
 };
 
 struct sctp_ifwdtsn_chunk {
@@ -658,7 +658,7 @@ struct sctp_addip_param {
 
 struct sctp_addiphdr {
        __be32  serial;
-       __u8    params[0];
+       __u8    params[];
 };
 
 struct sctp_addip_chunk {
@@ -718,7 +718,7 @@ struct sctp_addip_chunk {
 struct sctp_authhdr {
        __be16 shkey_id;
        __be16 hmac_id;
-       __u8   hmac[0];
+       __u8   hmac[];
 };
 
 struct sctp_auth_chunk {
@@ -733,7 +733,7 @@ struct sctp_infox {
 
 struct sctp_reconf_chunk {
        struct sctp_chunkhdr chunk_hdr;
-       __u8 params[0];
+       __u8 params[];
 };
 
 struct sctp_strreset_outreq {
@@ -741,13 +741,13 @@ struct sctp_strreset_outreq {
        __be32 request_seq;
        __be32 response_seq;
        __be32 send_reset_at_tsn;
-       __be16 list_of_streams[0];
+       __be16 list_of_streams[];
 };
 
 struct sctp_strreset_inreq {
        struct sctp_paramhdr param_hdr;
        __be32 request_seq;
-       __be16 list_of_streams[0];
+       __be16 list_of_streams[];
 };
 
 struct sctp_strreset_tsnreq {
index 299cbb8..44073d0 100644 (file)
@@ -124,7 +124,7 @@ struct tifm_adapter {
        int                 (*has_ms_pif)(struct tifm_adapter *fm,
                                          struct tifm_dev *sock);
 
-       struct tifm_dev     *sockets[0];
+       struct tifm_dev     *sockets[];
 };
 
 struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets,
index 7bcadca..0a76ddc 100644 (file)
@@ -301,13 +301,14 @@ copy_struct_from_user(void *dst, size_t ksize, const void __user *src,
        return 0;
 }
 
-bool probe_kernel_read_allowed(const void *unsafe_src, size_t size);
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size);
 
-extern long probe_kernel_read(void *dst, const void *src, size_t size);
-extern long probe_user_read(void *dst, const void __user *src, size_t size);
+long copy_from_kernel_nofault(void *dst, const void *src, size_t size);
+long notrace copy_to_kernel_nofault(void *dst, const void *src, size_t size);
 
-extern long notrace probe_kernel_write(void *dst, const void *src, size_t size);
-extern long notrace probe_user_write(void __user *dst, const void *src, size_t size);
+long copy_from_user_nofault(void *dst, const void __user *src, size_t size);
+long notrace copy_to_user_nofault(void __user *dst, const void *src,
+               size_t size);
 
 long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr,
                long count);
@@ -317,14 +318,16 @@ long strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
 long strnlen_user_nofault(const void __user *unsafe_addr, long count);
 
 /**
- * probe_kernel_address(): safely attempt to read from a location
- * @addr: address to read from
- * @retval: read into this variable
+ * get_kernel_nofault(): safely attempt to read from a location
+ * @val: read into this variable
+ * @ptr: address to read from
  *
  * Returns 0 on success, or -EFAULT.
  */
-#define probe_kernel_address(addr, retval)             \
-       probe_kernel_read(&retval, addr, sizeof(retval))
+#define get_kernel_nofault(val, ptr) ({                                \
+       const typeof(val) *__gk_ptr = (ptr);                    \
+       copy_from_kernel_nofault(&(val), __gk_ptr, sizeof(val));\
+})
 
 #ifndef user_access_begin
 #define user_access_begin(ptr,len) access_ok(ptr, len)
index d7338bf..16e8b2f 100644 (file)
@@ -161,10 +161,51 @@ struct nf_flow_route {
 struct flow_offload *flow_offload_alloc(struct nf_conn *ct);
 void flow_offload_free(struct flow_offload *flow);
 
-int nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
-                                flow_setup_cb_t *cb, void *cb_priv);
-void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
-                                 flow_setup_cb_t *cb, void *cb_priv);
+static inline int
+nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
+                            flow_setup_cb_t *cb, void *cb_priv)
+{
+       struct flow_block *block = &flow_table->flow_block;
+       struct flow_block_cb *block_cb;
+       int err = 0;
+
+       down_write(&flow_table->flow_block_lock);
+       block_cb = flow_block_cb_lookup(block, cb, cb_priv);
+       if (block_cb) {
+               err = -EEXIST;
+               goto unlock;
+       }
+
+       block_cb = flow_block_cb_alloc(cb, cb_priv, cb_priv, NULL);
+       if (IS_ERR(block_cb)) {
+               err = PTR_ERR(block_cb);
+               goto unlock;
+       }
+
+       list_add_tail(&block_cb->list, &block->cb_list);
+
+unlock:
+       up_write(&flow_table->flow_block_lock);
+       return err;
+}
+
+static inline void
+nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
+                            flow_setup_cb_t *cb, void *cb_priv)
+{
+       struct flow_block *block = &flow_table->flow_block;
+       struct flow_block_cb *block_cb;
+
+       down_write(&flow_table->flow_block_lock);
+       block_cb = flow_block_cb_lookup(block, cb, cb_priv);
+       if (block_cb) {
+               list_del(&block_cb->list);
+               flow_block_cb_free(block_cb);
+       } else {
+               WARN_ON(true);
+       }
+       up_write(&flow_table->flow_block_lock);
+}
 
 int flow_offload_route_init(struct flow_offload *flow,
                            const struct nf_flow_route *route);
index 79654bc..8250d6f 100644 (file)
@@ -66,7 +66,16 @@ static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a)
 #endif /* CONFIG_NF_CONNTRACK */
 
 #if IS_ENABLED(CONFIG_NET_ACT_CT)
-void tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie);
+static inline void
+tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie)
+{
+       enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK;
+       struct nf_conn *ct;
+
+       ct = (struct nf_conn *)(cookie & NFCT_PTRMASK);
+       nf_conntrack_get(&ct->ct_general);
+       nf_ct_set(skb, ct, ctinfo);
+}
 #else
 static inline void
 tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) { }
index 1257f26..93b1142 100644 (file)
@@ -254,7 +254,6 @@ TRACE_EVENT(block_bio_bounce,
  * block_bio_complete - completed all work on the block operation
  * @q: queue holding the block operation
  * @bio: block operation completed
- * @error: io error value
  *
  * This tracepoint indicates there is no further work to do on this
  * block IO operation @bio.
index 379a612..f44eb0a 100644 (file)
@@ -262,6 +262,7 @@ struct fsxattr {
 #define FS_EA_INODE_FL                 0x00200000 /* Inode used for large EA */
 #define FS_EOFBLOCKS_FL                        0x00400000 /* Reserved for ext4 */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
+#define FS_DAX_FL                      0x02000000 /* Inode is DAX */
 #define FS_INLINE_DATA_FL              0x10000000 /* Reserved for ext4 */
 #define FS_PROJINHERIT_FL              0x20000000 /* Create with parents projid */
 #define FS_CASEFOLD_FL                 0x40000000 /* Folder is case insensitive */
index de5d902..0e09dc5 100644 (file)
@@ -244,6 +244,7 @@ struct nd_cmd_pkg {
 #define NVDIMM_FAMILY_HPE2 2
 #define NVDIMM_FAMILY_MSFT 3
 #define NVDIMM_FAMILY_HYPERV 4
+#define NVDIMM_FAMILY_PAPR 5
 
 #define ND_IOCTL_CALL                  _IOWR(ND_IOCTL, ND_CMD_CALL,\
                                        struct nd_cmd_pkg)
index c1395b5..9463db2 100644 (file)
@@ -7,6 +7,7 @@
   Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
   Copyright (c) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
   Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
+  Copyright (c) 2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
 */
 
 #include <linux/libc-compat.h>
@@ -31,6 +32,9 @@
 #define XATTR_BTRFS_PREFIX "btrfs."
 #define XATTR_BTRFS_PREFIX_LEN (sizeof(XATTR_BTRFS_PREFIX) - 1)
 
+#define XATTR_HURD_PREFIX "gnu."
+#define XATTR_HURD_PREFIX_LEN (sizeof(XATTR_HURD_PREFIX) - 1)
+
 #define XATTR_SECURITY_PREFIX  "security."
 #define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
 
index ccc0f98..bc8d25f 100644 (file)
@@ -169,18 +169,18 @@ int __weak kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 {
        int err;
 
-       err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
+       err = copy_from_kernel_nofault(bpt->saved_instr, (char *)bpt->bpt_addr,
                                BREAK_INSTR_SIZE);
        if (err)
                return err;
-       err = probe_kernel_write((char *)bpt->bpt_addr,
+       err = copy_to_kernel_nofault((char *)bpt->bpt_addr,
                                 arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE);
        return err;
 }
 
 int __weak kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
 {
-       return probe_kernel_write((char *)bpt->bpt_addr,
+       return copy_to_kernel_nofault((char *)bpt->bpt_addr,
                                  (char *)bpt->saved_instr, BREAK_INSTR_SIZE);
 }
 
index 4b280fc..61774ae 100644 (file)
@@ -247,7 +247,7 @@ char *kgdb_mem2hex(char *mem, char *buf, int count)
         */
        tmp = buf + count;
 
-       err = probe_kernel_read(tmp, mem, count);
+       err = copy_from_kernel_nofault(tmp, mem, count);
        if (err)
                return NULL;
        while (count > 0) {
@@ -283,7 +283,7 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
                *tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
        }
 
-       return probe_kernel_write(mem, tmp_raw, count);
+       return copy_to_kernel_nofault(mem, tmp_raw, count);
 }
 
 /*
@@ -335,7 +335,7 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count)
                size++;
        }
 
-       return probe_kernel_write(mem, c, size);
+       return copy_to_kernel_nofault(mem, c, size);
 }
 
 #if DBG_MAX_REG_NUM > 0
index ec19056..5c79490 100644 (file)
@@ -2326,7 +2326,8 @@ void kdb_ps1(const struct task_struct *p)
        int cpu;
        unsigned long tmp;
 
-       if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long)))
+       if (!p ||
+           copy_from_kernel_nofault(&tmp, (char *)p, sizeof(unsigned long)))
                return;
 
        cpu = kdb_process_cpu(p);
index b8e6306..004c5b6 100644 (file)
@@ -325,7 +325,7 @@ char *kdb_strdup(const char *str, gfp_t type)
  */
 int kdb_getarea_size(void *res, unsigned long addr, size_t size)
 {
-       int ret = probe_kernel_read((char *)res, (char *)addr, size);
+       int ret = copy_from_kernel_nofault((char *)res, (char *)addr, size);
        if (ret) {
                if (!KDB_STATE(SUPPRESS)) {
                        kdb_printf("kdb_getarea: Bad address 0x%lx\n", addr);
@@ -350,7 +350,7 @@ int kdb_getarea_size(void *res, unsigned long addr, size_t size)
  */
 int kdb_putarea_size(unsigned long addr, void *res, size_t size)
 {
-       int ret = probe_kernel_read((char *)addr, (char *)res, size);
+       int ret = copy_from_kernel_nofault((char *)addr, (char *)res, size);
        if (ret) {
                if (!KDB_STATE(SUPPRESS)) {
                        kdb_printf("kdb_putarea: Bad address 0x%lx\n", addr);
@@ -624,7 +624,8 @@ char kdb_task_state_char (const struct task_struct *p)
        char state;
        unsigned long tmp;
 
-       if (!p || probe_kernel_read(&tmp, (char *)p, sizeof(unsigned long)))
+       if (!p ||
+           copy_from_kernel_nofault(&tmp, (char *)p, sizeof(unsigned long)))
                return 'E';
 
        cpu = kdb_process_cpu(p);
index d006668..a0ce3c1 100644 (file)
@@ -73,18 +73,18 @@ config SWIOTLB
 config DMA_NONCOHERENT_MMAP
        bool
 
+config DMA_COHERENT_POOL
+       bool
+
 config DMA_REMAP
+       bool
        depends on MMU
        select GENERIC_ALLOCATOR
        select DMA_NONCOHERENT_MMAP
-       bool
-
-config DMA_COHERENT_POOL
-       bool
-       select DMA_REMAP
 
 config DMA_DIRECT_REMAP
        bool
+       select DMA_REMAP
        select DMA_COHERENT_POOL
 
 config DMA_CMA
index 35bb51c..8cfa012 100644 (file)
@@ -175,10 +175,9 @@ static int __init dma_atomic_pool_init(void)
         * sizes to 128KB per 1GB of memory, min 128KB, max MAX_ORDER-1.
         */
        if (!atomic_pool_size) {
-               atomic_pool_size = max(totalram_pages() >> PAGE_SHIFT, 1UL) *
-                                       SZ_128K;
-               atomic_pool_size = min_t(size_t, atomic_pool_size,
-                                        1 << (PAGE_SHIFT + MAX_ORDER-1));
+               unsigned long pages = totalram_pages() / (SZ_1G / SZ_128K);
+               pages = min_t(unsigned long, pages, MAX_ORDER_NR_PAGES);
+               atomic_pool_size = max_t(size_t, pages << PAGE_SHIFT, SZ_128K);
        }
        INIT_WORK(&atomic_pool_work, atomic_pool_work_fn);
 
index 50cd84f..4a904cc 100644 (file)
 
 
 static int kprobes_initialized;
+/* kprobe_table can be accessed by
+ * - Normal hlist traversal and RCU add/del under kprobe_mutex is held.
+ * Or
+ * - RCU hlist traversal under disabling preempt (breakpoint handlers)
+ */
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -326,7 +331,8 @@ struct kprobe *get_kprobe(void *addr)
        struct kprobe *p;
 
        head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
-       hlist_for_each_entry_rcu(p, head, hlist) {
+       hlist_for_each_entry_rcu(p, head, hlist,
+                                lockdep_is_held(&kprobe_mutex)) {
                if (p->addr == addr)
                        return p;
        }
@@ -586,11 +592,12 @@ static void kprobe_optimizer(struct work_struct *work)
        mutex_unlock(&module_mutex);
        mutex_unlock(&text_mutex);
        cpus_read_unlock();
-       mutex_unlock(&kprobe_mutex);
 
        /* Step 5: Kick optimizer again if needed */
        if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list))
                kick_kprobe_optimizer();
+
+       mutex_unlock(&kprobe_mutex);
 }
 
 /* Wait for completing optimization and unoptimization */
@@ -668,8 +675,6 @@ static void force_unoptimize_kprobe(struct optimized_kprobe *op)
        lockdep_assert_cpus_held();
        arch_unoptimize_kprobe(op);
        op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
-       if (kprobe_disabled(&op->kp))
-               arch_disarm_kprobe(&op->kp);
 }
 
 /* Unoptimize a kprobe if p is optimized */
@@ -849,7 +854,7 @@ static void optimize_all_kprobes(void)
        kprobes_allow_optimization = true;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, head, hlist)
+               hlist_for_each_entry(p, head, hlist)
                        if (!kprobe_disabled(p))
                                optimize_kprobe(p);
        }
@@ -876,7 +881,7 @@ static void unoptimize_all_kprobes(void)
        kprobes_allow_optimization = false;
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, head, hlist) {
+               hlist_for_each_entry(p, head, hlist) {
                        if (!kprobe_disabled(p))
                                unoptimize_kprobe(p, false);
                }
@@ -1236,6 +1241,26 @@ __releases(hlist_lock)
 }
 NOKPROBE_SYMBOL(kretprobe_table_unlock);
 
+struct kprobe kprobe_busy = {
+       .addr = (void *) get_kprobe,
+};
+
+void kprobe_busy_begin(void)
+{
+       struct kprobe_ctlblk *kcb;
+
+       preempt_disable();
+       __this_cpu_write(current_kprobe, &kprobe_busy);
+       kcb = get_kprobe_ctlblk();
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+}
+
+void kprobe_busy_end(void)
+{
+       __this_cpu_write(current_kprobe, NULL);
+       preempt_enable();
+}
+
 /*
  * This function is called from finish_task_switch when task tk becomes dead,
  * so that we can recycle any function-return probe instances associated
@@ -1253,6 +1278,8 @@ void kprobe_flush_task(struct task_struct *tk)
                /* Early boot.  kretprobe_table_locks not yet initialized. */
                return;
 
+       kprobe_busy_begin();
+
        INIT_HLIST_HEAD(&empty_rp);
        hash = hash_ptr(tk, KPROBE_HASH_BITS);
        head = &kretprobe_inst_table[hash];
@@ -1266,6 +1293,8 @@ void kprobe_flush_task(struct task_struct *tk)
                hlist_del(&ri->hlist);
                kfree(ri);
        }
+
+       kprobe_busy_end();
 }
 NOKPROBE_SYMBOL(kprobe_flush_task);
 
@@ -1499,12 +1528,14 @@ static struct kprobe *__get_valid_kprobe(struct kprobe *p)
 {
        struct kprobe *ap, *list_p;
 
+       lockdep_assert_held(&kprobe_mutex);
+
        ap = get_kprobe(p->addr);
        if (unlikely(!ap))
                return NULL;
 
        if (p != ap) {
-               list_for_each_entry_rcu(list_p, &ap->list, list)
+               list_for_each_entry(list_p, &ap->list, list)
                        if (list_p == p)
                        /* kprobe p is a valid probe */
                                goto valid;
@@ -1669,7 +1700,9 @@ static int aggr_kprobe_disabled(struct kprobe *ap)
 {
        struct kprobe *kp;
 
-       list_for_each_entry_rcu(kp, &ap->list, list)
+       lockdep_assert_held(&kprobe_mutex);
+
+       list_for_each_entry(kp, &ap->list, list)
                if (!kprobe_disabled(kp))
                        /*
                         * There is an active probe on the list.
@@ -1748,7 +1781,7 @@ static int __unregister_kprobe_top(struct kprobe *p)
        else {
                /* If disabling probe has special handlers, update aggrprobe */
                if (p->post_handler && !kprobe_gone(p)) {
-                       list_for_each_entry_rcu(list_p, &ap->list, list) {
+                       list_for_each_entry(list_p, &ap->list, list) {
                                if ((list_p != p) && (list_p->post_handler))
                                        goto noclean;
                        }
@@ -2062,13 +2095,15 @@ static void kill_kprobe(struct kprobe *p)
 {
        struct kprobe *kp;
 
+       lockdep_assert_held(&kprobe_mutex);
+
        p->flags |= KPROBE_FLAG_GONE;
        if (kprobe_aggrprobe(p)) {
                /*
                 * If this is an aggr_kprobe, we have to list all the
                 * chained probes and mark them GONE.
                 */
-               list_for_each_entry_rcu(kp, &p->list, list)
+               list_for_each_entry(kp, &p->list, list)
                        kp->flags |= KPROBE_FLAG_GONE;
                p->post_handler = NULL;
                kill_optimized_kprobe(p);
@@ -2312,7 +2347,7 @@ static int kprobes_module_callback(struct notifier_block *nb,
        mutex_lock(&kprobe_mutex);
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
-               hlist_for_each_entry_rcu(p, head, hlist)
+               hlist_for_each_entry(p, head, hlist)
                        if (within_module_init((unsigned long)p->addr, mod) ||
                            (checkcore &&
                             within_module_core((unsigned long)p->addr, mod))) {
@@ -2550,7 +2585,7 @@ static int arm_all_kprobes(void)
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
                /* Arm all kprobes on a best-effort basis */
-               hlist_for_each_entry_rcu(p, head, hlist) {
+               hlist_for_each_entry(p, head, hlist) {
                        if (!kprobe_disabled(p)) {
                                err = arm_kprobe(p);
                                if (err)  {
@@ -2593,7 +2628,7 @@ static int disarm_all_kprobes(void)
        for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
                head = &kprobe_table[i];
                /* Disarm all kprobes on a best-effort basis */
-               hlist_for_each_entry_rcu(p, head, hlist) {
+               hlist_for_each_entry(p, head, hlist) {
                        if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) {
                                err = disarm_kprobe(p, false);
                                if (err) {
index 8e3d2d7..132f84a 100644 (file)
@@ -201,7 +201,7 @@ void *kthread_probe_data(struct task_struct *task)
        struct kthread *kthread = to_kthread(task);
        void *data = NULL;
 
-       probe_kernel_read(&data, &kthread->data, sizeof(data));
+       copy_from_kernel_nofault(&data, &kthread->data, sizeof(data));
        return data;
 }
 
index 5773f0b..5ef0484 100644 (file)
@@ -3,6 +3,9 @@
  * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
  *
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/blkdev.h>
 #include <linux/blktrace_api.h>
@@ -344,7 +347,8 @@ static int __blk_trace_remove(struct request_queue *q)
 {
        struct blk_trace *bt;
 
-       bt = xchg(&q->blk_trace, NULL);
+       bt = rcu_replace_pointer(q->blk_trace, NULL,
+                                lockdep_is_held(&q->blk_trace_mutex));
        if (!bt)
                return -EINVAL;
 
@@ -494,6 +498,17 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
         */
        strreplace(buts->name, '/', '_');
 
+       /*
+        * bdev can be NULL, as with scsi-generic, this is a helpful as
+        * we can be.
+        */
+       if (rcu_dereference_protected(q->blk_trace,
+                                     lockdep_is_held(&q->blk_trace_mutex))) {
+               pr_warn("Concurrent blktraces are not allowed on %s\n",
+                       buts->name);
+               return -EBUSY;
+       }
+
        bt = kzalloc(sizeof(*bt), GFP_KERNEL);
        if (!bt)
                return -ENOMEM;
@@ -543,10 +558,7 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
        bt->pid = buts->pid;
        bt->trace_state = Blktrace_setup;
 
-       ret = -EBUSY;
-       if (cmpxchg(&q->blk_trace, NULL, bt))
-               goto err;
-
+       rcu_assign_pointer(q->blk_trace, bt);
        get_probe_ref();
 
        ret = 0;
@@ -1629,7 +1641,8 @@ static int blk_trace_remove_queue(struct request_queue *q)
 {
        struct blk_trace *bt;
 
-       bt = xchg(&q->blk_trace, NULL);
+       bt = rcu_replace_pointer(q->blk_trace, NULL,
+                                lockdep_is_held(&q->blk_trace_mutex));
        if (bt == NULL)
                return -EINVAL;
 
@@ -1661,10 +1674,7 @@ static int blk_trace_setup_queue(struct request_queue *q,
 
        blk_trace_setup_lba(bt, bdev);
 
-       ret = -EBUSY;
-       if (cmpxchg(&q->blk_trace, NULL, bt))
-               goto free_bt;
-
+       rcu_assign_pointer(q->blk_trace, bt);
        get_probe_ref();
        return 0;
 
index e729c9e..dc05626 100644 (file)
@@ -141,7 +141,7 @@ bpf_probe_read_user_common(void *dst, u32 size, const void __user *unsafe_ptr)
 {
        int ret;
 
-       ret = probe_user_read(dst, unsafe_ptr, size);
+       ret = copy_from_user_nofault(dst, unsafe_ptr, size);
        if (unlikely(ret < 0))
                memset(dst, 0, size);
        return ret;
@@ -196,7 +196,7 @@ bpf_probe_read_kernel_common(void *dst, u32 size, const void *unsafe_ptr)
 
        if (unlikely(ret < 0))
                goto fail;
-       ret = probe_kernel_read(dst, unsafe_ptr, size);
+       ret = copy_from_kernel_nofault(dst, unsafe_ptr, size);
        if (unlikely(ret < 0))
                goto fail;
        return ret;
@@ -326,7 +326,7 @@ BPF_CALL_3(bpf_probe_write_user, void __user *, unsafe_ptr, const void *, src,
        if (unlikely(!nmi_uaccess_okay()))
                return -EPERM;
 
-       return probe_user_write(unsafe_ptr, src, size);
+       return copy_to_user_nofault(unsafe_ptr, src, size);
 }
 
 static const struct bpf_func_proto bpf_probe_write_user_proto = {
@@ -661,7 +661,7 @@ BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size,
 
                        copy_size = (fmt[i + 2] == '4') ? 4 : 16;
 
-                       err = probe_kernel_read(bufs->buf[memcpy_cnt],
+                       err = copy_from_kernel_nofault(bufs->buf[memcpy_cnt],
                                                (void *) (long) args[fmt_cnt],
                                                copy_size);
                        if (err < 0)
index c163c35..1903b80 100644 (file)
@@ -2260,7 +2260,7 @@ ftrace_find_tramp_ops_next(struct dyn_ftrace *rec,
 
                if (hash_contains_ip(ip, op->func_hash))
                        return op;
-       } 
+       }
 
        return NULL;
 }
@@ -3599,7 +3599,7 @@ static int t_show(struct seq_file *m, void *v)
                        if (direct)
                                seq_printf(m, "\n\tdirect-->%pS", (void *)direct);
                }
-       }       
+       }
 
        seq_putc(m, '\n');
 
@@ -7151,6 +7151,10 @@ static int pid_open(struct inode *inode, struct file *file, int type)
        case TRACE_NO_PIDS:
                seq_ops = &ftrace_no_pid_sops;
                break;
+       default:
+               trace_array_put(tr);
+               WARN_ON_ONCE(1);
+               return -EINVAL;
        }
 
        ret = seq_open(file, seq_ops);
@@ -7229,6 +7233,10 @@ pid_write(struct file *filp, const char __user *ubuf,
                other_pids = rcu_dereference_protected(tr->function_pids,
                                             lockdep_is_held(&ftrace_lock));
                break;
+       default:
+               ret = -EINVAL;
+               WARN_ON_ONCE(1);
+               goto out;
        }
 
        ret = trace_pid_write(filtered_pids, &pid_list, ubuf, cnt);
index ec44b0e..bb62269 100644 (file)
@@ -3570,7 +3570,6 @@ static void *s_next(struct seq_file *m, void *v, loff_t *pos)
 
 void tracing_iter_reset(struct trace_iterator *iter, int cpu)
 {
-       struct ring_buffer_event *event;
        struct ring_buffer_iter *buf_iter;
        unsigned long entries = 0;
        u64 ts;
@@ -3588,7 +3587,7 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu)
         * that a reset never took place on a cpu. This is evident
         * by the timestamp being before the start of the buffer.
         */
-       while ((event = ring_buffer_iter_peek(buf_iter, &ts))) {
+       while (ring_buffer_iter_peek(buf_iter, &ts)) {
                if (ts >= iter->array_buffer->time_start)
                        break;
                entries++;
index def769d..13db400 100644 (file)
@@ -61,6 +61,9 @@ enum trace_type {
 #undef __field_desc
 #define __field_desc(type, container, item)
 
+#undef __field_packed
+#define __field_packed(type, container, item)
+
 #undef __array
 #define __array(type, item, size)      type    item[size];
 
index a523da0..18c4a58 100644 (file)
@@ -78,8 +78,8 @@ FTRACE_ENTRY_PACKED(funcgraph_entry, ftrace_graph_ent_entry,
 
        F_STRUCT(
                __field_struct( struct ftrace_graph_ent,        graph_ent       )
-               __field_desc(   unsigned long,  graph_ent,      func            )
-               __field_desc(   int,            graph_ent,      depth           )
+               __field_packed( unsigned long,  graph_ent,      func            )
+               __field_packed( int,            graph_ent,      depth           )
        ),
 
        F_printk("--> %ps (%d)", (void *)__entry->func, __entry->depth)
@@ -92,11 +92,11 @@ FTRACE_ENTRY_PACKED(funcgraph_exit, ftrace_graph_ret_entry,
 
        F_STRUCT(
                __field_struct( struct ftrace_graph_ret,        ret     )
-               __field_desc(   unsigned long,  ret,            func    )
-               __field_desc(   unsigned long,  ret,            overrun )
-               __field_desc(   unsigned long long, ret,        calltime)
-               __field_desc(   unsigned long long, ret,        rettime )
-               __field_desc(   int,            ret,            depth   )
+               __field_packed( unsigned long,  ret,            func    )
+               __field_packed( unsigned long,  ret,            overrun )
+               __field_packed( unsigned long long, ret,        calltime)
+               __field_packed( unsigned long long, ret,        rettime )
+               __field_packed( int,            ret,            depth   )
        ),
 
        F_printk("<-- %ps (%d) (start: %llx  end: %llx) over: %d",
index 77ce5a3..70d3d0a 100644 (file)
@@ -45,6 +45,9 @@ static int ftrace_event_register(struct trace_event_call *call,
 #undef __field_desc
 #define __field_desc(type, container, item)            type item;
 
+#undef __field_packed
+#define __field_packed(type, container, item)          type item;
+
 #undef __array
 #define __array(type, item, size)                      type item[size];
 
@@ -85,6 +88,13 @@ static void __always_unused ____ftrace_check_##name(void)            \
        .size = sizeof(_type), .align = __alignof__(_type),             \
        is_signed_type(_type), .filter_type = _filter_type },
 
+
+#undef __field_ext_packed
+#define __field_ext_packed(_type, _item, _filter_type) {       \
+       .type = #_type, .name = #_item,                         \
+       .size = sizeof(_type), .align = 1,                      \
+       is_signed_type(_type), .filter_type = _filter_type },
+
 #undef __field
 #define __field(_type, _item) __field_ext(_type, _item, FILTER_OTHER)
 
@@ -94,6 +104,9 @@ static void __always_unused ____ftrace_check_##name(void)            \
 #undef __field_desc
 #define __field_desc(_type, _container, _item) __field_ext(_type, _item, FILTER_OTHER)
 
+#undef __field_packed
+#define __field_packed(_type, _container, _item) __field_ext_packed(_type, _item, FILTER_OTHER)
+
 #undef __array
 #define __array(_type, _item, _len) {                                  \
        .type = #_type"["__stringify(_len)"]", .name = #_item,          \
@@ -129,6 +142,9 @@ static struct trace_event_fields ftrace_event_fields_##name[] = {   \
 #undef __field_desc
 #define __field_desc(type, container, item)
 
+#undef __field_packed
+#define __field_packed(type, container, item)
+
 #undef __array
 #define __array(type, item, len)
 
index 8a4c8d5..dd4dff7 100644 (file)
@@ -42,7 +42,7 @@ static int allocate_ftrace_ops(struct trace_array *tr)
        if (!ops)
                return -ENOMEM;
 
-       /* Currently only the non stack verision is supported */
+       /* Currently only the non stack version is supported */
        ops->func = function_trace_call;
        ops->flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_PID;
 
index 6048f1b..aefb606 100644 (file)
@@ -1222,7 +1222,7 @@ fetch_store_strlen(unsigned long addr)
 #endif
 
        do {
-               ret = probe_kernel_read(&c, (u8 *)addr + len, 1);
+               ret = copy_from_kernel_nofault(&c, (u8 *)addr + len, 1);
                len++;
        } while (c && ret == 0 && len < MAX_STRING_SIZE);
 
@@ -1290,7 +1290,7 @@ probe_mem_read_user(void *dest, void *src, size_t size)
 {
        const void __user *uaddr =  (__force const void __user *)src;
 
-       return probe_user_read(dest, uaddr, size);
+       return copy_from_user_nofault(dest, uaddr, size);
 }
 
 static nokprobe_inline int
@@ -1300,7 +1300,7 @@ probe_mem_read(void *dest, void *src, size_t size)
        if ((unsigned long)src < TASK_SIZE)
                return probe_mem_read_user(dest, src, size);
 #endif
-       return probe_kernel_read(dest, src, size);
+       return copy_from_kernel_nofault(dest, src, size);
 }
 
 /* Note that we don't verify it, since the code does not come from user space */
index b8a928e..d2867cc 100644 (file)
@@ -639,8 +639,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
                        ret = -EINVAL;
                        goto fail;
                }
-               if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM) ||
-                    parg->count) {
+               if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM ||
+                    code->op == FETCH_OP_DATA) || parg->count) {
                        /*
                         * IMM, DATA and COMM is pointing actual address, those
                         * must be kept, and if parg->count != 0, this is an
index a0ff9e2..a22b628 100644 (file)
@@ -236,7 +236,7 @@ struct trace_probe_event {
        struct trace_event_call         call;
        struct list_head                files;
        struct list_head                probes;
-       struct trace_uprobe_filter      filter[0];
+       struct trace_uprobe_filter      filter[];
 };
 
 struct trace_probe {
index 9fbe1e2..c41c3c1 100644 (file)
@@ -4638,11 +4638,11 @@ void print_worker_info(const char *log_lvl, struct task_struct *task)
         * Carefully copy the associated workqueue's workfn, name and desc.
         * Keep the original last '\0' in case the original is garbage.
         */
-       probe_kernel_read(&fn, &worker->current_func, sizeof(fn));
-       probe_kernel_read(&pwq, &worker->current_pwq, sizeof(pwq));
-       probe_kernel_read(&wq, &pwq->wq, sizeof(wq));
-       probe_kernel_read(name, wq->name, sizeof(name) - 1);
-       probe_kernel_read(desc, worker->desc, sizeof(desc) - 1);
+       copy_from_kernel_nofault(&fn, &worker->current_func, sizeof(fn));
+       copy_from_kernel_nofault(&pwq, &worker->current_pwq, sizeof(pwq));
+       copy_from_kernel_nofault(&wq, &pwq->wq, sizeof(wq));
+       copy_from_kernel_nofault(name, wq->name, sizeof(name) - 1);
+       copy_from_kernel_nofault(desc, worker->desc, sizeof(desc) - 1);
 
        if (fn || name[0] || desc[0]) {
                printk("%sWorkqueue: %s %ps", log_lvl, name, fn);
index d74ac0f..9ad9210 100644 (file)
@@ -229,7 +229,6 @@ config DEBUG_INFO_COMPRESSED
        bool "Compressed debugging information"
        depends on DEBUG_INFO
        depends on $(cc-option,-gz=zlib)
-       depends on $(as-option,-Wa$(comma)--compress-debug-sections=zlib)
        depends on $(ld-option,--compress-debug-sections=zlib)
        help
          Compress the debug information using zlib.  Requires GCC 5.0+ or Clang
index 4e865d4..707453f 100644 (file)
@@ -91,6 +91,7 @@ int seq_buf_printf(struct seq_buf *s, const char *fmt, ...)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(seq_buf_printf);
 
 #ifdef CONFIG_BINARY_PRINTF
 /**
index f258743..bd7c7ff 100644 (file)
@@ -419,8 +419,8 @@ static bool test_kernel_ptr(unsigned long addr, int size)
        /* should be at least readable kernel address */
        if (access_ok(ptr, 1) ||
            access_ok(ptr + size - 1, 1) ||
-           probe_kernel_address(ptr, buf) ||
-           probe_kernel_address(ptr + size - 1, buf)) {
+           get_kernel_nofault(buf, ptr) ||
+           get_kernel_nofault(buf, ptr + size - 1)) {
                pr_err("invalid kernel ptr: %#lx\n", addr);
                return true;
        }
@@ -437,7 +437,7 @@ static bool __maybe_unused test_magic(unsigned long addr, int offset,
        if (!addr)
                return false;
 
-       if (probe_kernel_address(ptr, magic) || magic != expected) {
+       if (get_kernel_nofault(magic, ptr) || magic != expected) {
                pr_err("invalid magic at %#lx + %#x = %#x, expected %#x\n",
                       addr, offset, magic, expected);
                return true;
index 72c1abf..da13793 100644 (file)
@@ -979,10 +979,10 @@ err_check_expect_stats2:
 err_world2_obj_get:
        for (i--; i >= 0; i--)
                world_obj_put(&world2, objagg, hints_case->key_ids[i]);
-       objagg_hints_put(hints);
-       objagg_destroy(objagg2);
        i = hints_case->key_ids_count;
+       objagg_destroy(objagg2);
 err_check_expect_hints_stats:
+       objagg_hints_put(hints);
 err_hints_get:
 err_check_expect_stats:
 err_world_obj_get:
index b5b1de8..4f37651 100644 (file)
@@ -120,9 +120,9 @@ void __dump_page(struct page *page, const char *reason)
                 * mapping can be invalid pointer and we don't want to crash
                 * accessing it, so probe everything depending on it carefully
                 */
-               if (probe_kernel_read(&host, &mapping->host,
+               if (copy_from_kernel_nofault(&host, &mapping->host,
                                        sizeof(struct inode *)) ||
-                   probe_kernel_read(&a_ops, &mapping->a_ops,
+                   copy_from_kernel_nofault(&a_ops, &mapping->a_ops,
                                sizeof(struct address_space_operations *))) {
                        pr_warn("failed to read mapping->host or a_ops, mapping not a valid kernel address?\n");
                        goto out_mapping;
@@ -133,7 +133,7 @@ void __dump_page(struct page *page, const char *reason)
                        goto out_mapping;
                }
 
-               if (probe_kernel_read(&dentry_first,
+               if (copy_from_kernel_nofault(&dentry_first,
                        &host->i_dentry.first, sizeof(struct hlist_node *))) {
                        pr_warn("mapping->a_ops:%ps with invalid mapping->host inode address %px\n",
                                a_ops, host);
@@ -146,7 +146,7 @@ void __dump_page(struct page *page, const char *reason)
                }
 
                dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias);
-               if (probe_kernel_read(&dentry, dentry_ptr,
+               if (copy_from_kernel_nofault(&dentry, dentry_ptr,
                                                        sizeof(struct dentry))) {
                        pr_warn("mapping->aops:%ps with invalid mapping->host->i_dentry.first %px\n",
                                a_ops, dentry_ptr);
index de9e362..6f47697 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2196,7 +2196,7 @@ static inline pte_t gup_get_pte(pte_t *ptep)
  */
 static inline pte_t gup_get_pte(pte_t *ptep)
 {
-       return READ_ONCE(*ptep);
+       return ptep_get(ptep);
 }
 #endif /* CONFIG_GUP_GET_PTE_LOW_HIGH */
 
@@ -2425,7 +2425,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
        if (pte_end < end)
                end = pte_end;
 
-       pte = READ_ONCE(*ptep);
+       pte = huge_ptep_get(ptep);
 
        if (!pte_access_permitted(pte, flags & FOLL_WRITE))
                return 0;
index 88845ed..f98ff91 100644 (file)
@@ -6,14 +6,15 @@
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 
-bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size)
+bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src,
+               size_t size)
 {
        return true;
 }
 
 #ifdef HAVE_GET_KERNEL_NOFAULT
 
-#define probe_kernel_read_loop(dst, src, len, type, err_label)         \
+#define copy_from_kernel_nofault_loop(dst, src, len, type, err_label)  \
        while (len >= sizeof(type)) {                                   \
                __get_kernel_nofault(dst, src, type, err_label);                \
                dst += sizeof(type);                                    \
@@ -21,25 +22,25 @@ bool __weak probe_kernel_read_allowed(const void *unsafe_src, size_t size)
                len -= sizeof(type);                                    \
        }
 
-long probe_kernel_read(void *dst, const void *src, size_t size)
+long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
 {
-       if (!probe_kernel_read_allowed(src, size))
+       if (!copy_from_kernel_nofault_allowed(src, size))
                return -ERANGE;
 
        pagefault_disable();
-       probe_kernel_read_loop(dst, src, size, u64, Efault);
-       probe_kernel_read_loop(dst, src, size, u32, Efault);
-       probe_kernel_read_loop(dst, src, size, u16, Efault);
-       probe_kernel_read_loop(dst, src, size, u8, Efault);
+       copy_from_kernel_nofault_loop(dst, src, size, u64, Efault);
+       copy_from_kernel_nofault_loop(dst, src, size, u32, Efault);
+       copy_from_kernel_nofault_loop(dst, src, size, u16, Efault);
+       copy_from_kernel_nofault_loop(dst, src, size, u8, Efault);
        pagefault_enable();
        return 0;
 Efault:
        pagefault_enable();
        return -EFAULT;
 }
-EXPORT_SYMBOL_GPL(probe_kernel_read);
+EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
 
-#define probe_kernel_write_loop(dst, src, len, type, err_label)                \
+#define copy_to_kernel_nofault_loop(dst, src, len, type, err_label)    \
        while (len >= sizeof(type)) {                                   \
                __put_kernel_nofault(dst, src, type, err_label);                \
                dst += sizeof(type);                                    \
@@ -47,13 +48,13 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
                len -= sizeof(type);                                    \
        }
 
-long probe_kernel_write(void *dst, const void *src, size_t size)
+long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
 {
        pagefault_disable();
-       probe_kernel_write_loop(dst, src, size, u64, Efault);
-       probe_kernel_write_loop(dst, src, size, u32, Efault);
-       probe_kernel_write_loop(dst, src, size, u16, Efault);
-       probe_kernel_write_loop(dst, src, size, u8, Efault);
+       copy_to_kernel_nofault_loop(dst, src, size, u64, Efault);
+       copy_to_kernel_nofault_loop(dst, src, size, u32, Efault);
+       copy_to_kernel_nofault_loop(dst, src, size, u16, Efault);
+       copy_to_kernel_nofault_loop(dst, src, size, u8, Efault);
        pagefault_enable();
        return 0;
 Efault:
@@ -67,7 +68,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
 
        if (unlikely(count <= 0))
                return 0;
-       if (!probe_kernel_read_allowed(unsafe_addr, count))
+       if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
                return -ERANGE;
 
        pagefault_disable();
@@ -87,7 +88,7 @@ Efault:
 }
 #else /* HAVE_GET_KERNEL_NOFAULT */
 /**
- * probe_kernel_read(): safely attempt to read from kernel-space
+ * copy_from_kernel_nofault(): safely attempt to read from kernel-space
  * @dst: pointer to the buffer that shall take the data
  * @src: address to read from
  * @size: size of the data chunk
@@ -98,15 +99,15 @@ Efault:
  *
  * We ensure that the copy_from_user is executed in atomic context so that
  * do_page_fault() doesn't attempt to take mmap_lock.  This makes
- * probe_kernel_read() suitable for use within regions where the caller
+ * copy_from_kernel_nofault() suitable for use within regions where the caller
  * already holds mmap_lock, or other locks which nest inside mmap_lock.
  */
-long probe_kernel_read(void *dst, const void *src, size_t size)
+long copy_from_kernel_nofault(void *dst, const void *src, size_t size)
 {
        long ret;
        mm_segment_t old_fs = get_fs();
 
-       if (!probe_kernel_read_allowed(src, size))
+       if (!copy_from_kernel_nofault_allowed(src, size))
                return -ERANGE;
 
        set_fs(KERNEL_DS);
@@ -120,10 +121,10 @@ long probe_kernel_read(void *dst, const void *src, size_t size)
                return -EFAULT;
        return 0;
 }
-EXPORT_SYMBOL_GPL(probe_kernel_read);
+EXPORT_SYMBOL_GPL(copy_from_kernel_nofault);
 
 /**
- * probe_kernel_write(): safely attempt to write to a location
+ * copy_to_kernel_nofault(): safely attempt to write to a location
  * @dst: address to write to
  * @src: pointer to the data that shall be written
  * @size: size of the data chunk
@@ -131,7 +132,7 @@ EXPORT_SYMBOL_GPL(probe_kernel_read);
  * Safely write to address @dst from the buffer at @src.  If a kernel fault
  * happens, handle that and return -EFAULT.
  */
-long probe_kernel_write(void *dst, const void *src, size_t size)
+long copy_to_kernel_nofault(void *dst, const void *src, size_t size)
 {
        long ret;
        mm_segment_t old_fs = get_fs();
@@ -174,7 +175,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
 
        if (unlikely(count <= 0))
                return 0;
-       if (!probe_kernel_read_allowed(unsafe_addr, count))
+       if (!copy_from_kernel_nofault_allowed(unsafe_addr, count))
                return -ERANGE;
 
        set_fs(KERNEL_DS);
@@ -193,7 +194,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
 #endif /* HAVE_GET_KERNEL_NOFAULT */
 
 /**
- * probe_user_read(): safely attempt to read from a user-space location
+ * copy_from_user_nofault(): safely attempt to read from a user-space location
  * @dst: pointer to the buffer that shall take the data
  * @src: address to read from. This must be a user address.
  * @size: size of the data chunk
@@ -201,7 +202,7 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count)
  * Safely read from user address @src to the buffer at @dst. If a kernel fault
  * happens, handle that and return -EFAULT.
  */
-long probe_user_read(void *dst, const void __user *src, size_t size)
+long copy_from_user_nofault(void *dst, const void __user *src, size_t size)
 {
        long ret = -EFAULT;
        mm_segment_t old_fs = get_fs();
@@ -218,10 +219,10 @@ long probe_user_read(void *dst, const void __user *src, size_t size)
                return -EFAULT;
        return 0;
 }
-EXPORT_SYMBOL_GPL(probe_user_read);
+EXPORT_SYMBOL_GPL(copy_from_user_nofault);
 
 /**
- * probe_user_write(): safely attempt to write to a user-space location
+ * copy_to_user_nofault(): safely attempt to write to a user-space location
  * @dst: address to write to
  * @src: pointer to the data that shall be written
  * @size: size of the data chunk
@@ -229,7 +230,7 @@ EXPORT_SYMBOL_GPL(probe_user_read);
  * Safely write to address @dst from the buffer at @src.  If a kernel fault
  * happens, handle that and return -EFAULT.
  */
-long probe_user_write(void __user *dst, const void *src, size_t size)
+long copy_to_user_nofault(void __user *dst, const void *src, size_t size)
 {
        long ret = -EFAULT;
        mm_segment_t old_fs = get_fs();
@@ -246,7 +247,7 @@ long probe_user_write(void __user *dst, const void *src, size_t size)
                return -EFAULT;
        return 0;
 }
-EXPORT_SYMBOL_GPL(probe_user_write);
+EXPORT_SYMBOL_GPL(copy_to_user_nofault);
 
 /**
  * strncpy_from_user_nofault: - Copy a NUL terminated string from unsafe user
index 5e313fa..2a99df7 100644 (file)
@@ -25,7 +25,7 @@ void rodata_test(void)
        }
 
        /* test 2: write to the variable; this should fault */
-       if (!probe_kernel_write((void *)&rodata_test_data,
+       if (!copy_to_kernel_nofault((void *)&rodata_test_data,
                                (void *)&zero, sizeof(zero))) {
                pr_err("test data was not read only\n");
                return;
index b8f798b..fe81773 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -292,7 +292,7 @@ static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
                return get_freepointer(s, object);
 
        freepointer_addr = (unsigned long)object + s->offset;
-       probe_kernel_read(&p, (void **)freepointer_addr, sizeof(p));
+       copy_from_kernel_nofault(&p, (void **)freepointer_addr, sizeof(p));
        return freelist_ptr(s, p, freepointer_addr);
 }
 
index afe0e81..4e7edd7 100644 (file)
@@ -332,6 +332,7 @@ struct ceph_options *ceph_alloc_options(void)
        opt->mount_timeout = CEPH_MOUNT_TIMEOUT_DEFAULT;
        opt->osd_idle_ttl = CEPH_OSD_IDLE_TTL_DEFAULT;
        opt->osd_request_timeout = CEPH_OSD_REQUEST_TIMEOUT_DEFAULT;
+       opt->read_from_replica = CEPH_READ_FROM_REPLICA_DEFAULT;
        return opt;
 }
 EXPORT_SYMBOL(ceph_alloc_options);
@@ -490,16 +491,13 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
        case Opt_read_from_replica:
                switch (result.uint_32) {
                case Opt_read_from_replica_no:
-                       opt->osd_req_flags &= ~(CEPH_OSD_FLAG_BALANCE_READS |
-                                               CEPH_OSD_FLAG_LOCALIZE_READS);
+                       opt->read_from_replica = 0;
                        break;
                case Opt_read_from_replica_balance:
-                       opt->osd_req_flags |= CEPH_OSD_FLAG_BALANCE_READS;
-                       opt->osd_req_flags &= ~CEPH_OSD_FLAG_LOCALIZE_READS;
+                       opt->read_from_replica = CEPH_OSD_FLAG_BALANCE_READS;
                        break;
                case Opt_read_from_replica_localize:
-                       opt->osd_req_flags |= CEPH_OSD_FLAG_LOCALIZE_READS;
-                       opt->osd_req_flags &= ~CEPH_OSD_FLAG_BALANCE_READS;
+                       opt->read_from_replica = CEPH_OSD_FLAG_LOCALIZE_READS;
                        break;
                default:
                        BUG();
@@ -613,9 +611,9 @@ int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
                }
                seq_putc(m, ',');
        }
-       if (opt->osd_req_flags & CEPH_OSD_FLAG_BALANCE_READS) {
+       if (opt->read_from_replica == CEPH_OSD_FLAG_BALANCE_READS) {
                seq_puts(m, "read_from_replica=balance,");
-       } else if (opt->osd_req_flags & CEPH_OSD_FLAG_LOCALIZE_READS) {
+       } else if (opt->read_from_replica == CEPH_OSD_FLAG_LOCALIZE_READS) {
                seq_puts(m, "read_from_replica=localize,");
        }
 
index 4fea3c3..2db8b44 100644 (file)
@@ -445,8 +445,10 @@ static void target_copy(struct ceph_osd_request_target *dest,
        dest->size = src->size;
        dest->min_size = src->min_size;
        dest->sort_bitwise = src->sort_bitwise;
+       dest->recovery_deletes = src->recovery_deletes;
 
        dest->flags = src->flags;
+       dest->used_replica = src->used_replica;
        dest->paused = src->paused;
 
        dest->epoch = src->epoch;
@@ -1117,10 +1119,10 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc,
                                       truncate_size, truncate_seq);
        }
 
-       req->r_flags = flags;
        req->r_base_oloc.pool = layout->pool_id;
        req->r_base_oloc.pool_ns = ceph_try_get_string(layout->pool_ns);
        ceph_oid_printf(&req->r_base_oid, "%llx.%08llx", vino.ino, objnum);
+       req->r_flags = flags | osdc->client->options->read_from_replica;
 
        req->r_snapid = vino.snap;
        if (flags & CEPH_OSD_FLAG_WRITE)
@@ -2431,14 +2433,11 @@ promote:
 
 static void account_request(struct ceph_osd_request *req)
 {
-       struct ceph_osd_client *osdc = req->r_osdc;
-
        WARN_ON(req->r_flags & (CEPH_OSD_FLAG_ACK | CEPH_OSD_FLAG_ONDISK));
        WARN_ON(!(req->r_flags & (CEPH_OSD_FLAG_READ | CEPH_OSD_FLAG_WRITE)));
 
        req->r_flags |= CEPH_OSD_FLAG_ONDISK;
-       req->r_flags |= osdc->client->options->osd_req_flags;
-       atomic_inc(&osdc->num_requests);
+       atomic_inc(&req->r_osdc->num_requests);
 
        req->r_start_stamp = jiffies;
        req->r_start_latency = ktime_get();
index 83330a6..12fda8f 100644 (file)
@@ -4605,7 +4605,11 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
        if (tcp_ooo_try_coalesce(sk, tp->ooo_last_skb,
                                 skb, &fragstolen)) {
 coalesce_done:
-               tcp_grow_window(sk, skb);
+               /* For non sack flows, do not grow window to force DUPACK
+                * and trigger fast retransmit.
+                */
+               if (tcp_is_sack(tp))
+                       tcp_grow_window(sk, skb);
                kfree_skb_partial(skb, fragstolen);
                skb = NULL;
                goto add_sack;
@@ -4689,7 +4693,11 @@ add_sack:
                tcp_sack_new_ofo_skb(sk, seq, end_seq);
 end:
        if (skb) {
-               tcp_grow_window(sk, skb);
+               /* For non sack flows, do not grow window to force DUPACK
+                * and trigger fast retransmit.
+                */
+               if (tcp_is_sack(tp))
+                       tcp_grow_window(sk, skb);
                skb_condense(skb);
                skb_set_owner_r(skb, sk);
        }
index 7e12d21..8cd2782 100644 (file)
@@ -2615,6 +2615,7 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
                idev->mc_list = i->next;
 
                write_unlock_bh(&idev->lock);
+               ip6_mc_clear_src(i);
                ma_put(i);
                write_lock_bh(&idev->lock);
        }
index 809687d..db56535 100644 (file)
@@ -135,8 +135,6 @@ static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field)
                     ((nib & 0xF) << 8) | field);
 }
 
-#define MPTCP_PM_MAX_ADDR      4
-
 struct mptcp_addr_info {
        sa_family_t             family;
        __be16                  port;
@@ -234,10 +232,7 @@ static inline struct mptcp_data_frag *mptcp_rtx_head(const struct sock *sk)
 {
        struct mptcp_sock *msk = mptcp_sk(sk);
 
-       if (list_empty(&msk->rtx_queue))
-               return NULL;
-
-       return list_first_entry(&msk->rtx_queue, struct mptcp_data_frag, list);
+       return list_first_entry_or_null(&msk->rtx_queue, struct mptcp_data_frag, list);
 }
 
 struct mptcp_subflow_request_sock {
index bf13257..bbdb74b 100644 (file)
@@ -1053,8 +1053,10 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock)
        err = tcp_set_ulp(sf->sk, "mptcp");
        release_sock(sf->sk);
 
-       if (err)
+       if (err) {
+               sock_release(sf);
                return err;
+       }
 
        /* the newly created socket really belongs to the owning MPTCP master
         * socket, even if for additional subflows the allocation is performed
index d7bd8b1..832eabe 100644 (file)
@@ -939,7 +939,8 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
                        filter->mark.mask = 0xffffffff;
                }
        } else if (cda[CTA_MARK_MASK]) {
-               return ERR_PTR(-EINVAL);
+               err = -EINVAL;
+               goto err_filter;
        }
 #endif
        if (!cda[CTA_FILTER])
@@ -947,15 +948,17 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
 
        err = ctnetlink_parse_zone(cda[CTA_ZONE], &filter->zone);
        if (err < 0)
-               return ERR_PTR(err);
+               goto err_filter;
 
        err = ctnetlink_parse_filter(cda[CTA_FILTER], filter);
        if (err < 0)
-               return ERR_PTR(err);
+               goto err_filter;
 
        if (filter->orig_flags) {
-               if (!cda[CTA_TUPLE_ORIG])
-                       return ERR_PTR(-EINVAL);
+               if (!cda[CTA_TUPLE_ORIG]) {
+                       err = -EINVAL;
+                       goto err_filter;
+               }
 
                err = ctnetlink_parse_tuple_filter(cda, &filter->orig,
                                                   CTA_TUPLE_ORIG,
@@ -963,23 +966,32 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
                                                   &filter->zone,
                                                   filter->orig_flags);
                if (err < 0)
-                       return ERR_PTR(err);
+                       goto err_filter;
        }
 
        if (filter->reply_flags) {
-               if (!cda[CTA_TUPLE_REPLY])
-                       return ERR_PTR(-EINVAL);
+               if (!cda[CTA_TUPLE_REPLY]) {
+                       err = -EINVAL;
+                       goto err_filter;
+               }
 
                err = ctnetlink_parse_tuple_filter(cda, &filter->reply,
                                                   CTA_TUPLE_REPLY,
                                                   filter->family,
                                                   &filter->zone,
                                                   filter->orig_flags);
-               if (err < 0)
-                       return ERR_PTR(err);
+               if (err < 0) {
+                       err = -EINVAL;
+                       goto err_filter;
+               }
        }
 
        return filter;
+
+err_filter:
+       kfree(filter);
+
+       return ERR_PTR(err);
 }
 
 static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda)
index 6a3034f..afa8517 100644 (file)
@@ -387,51 +387,6 @@ static void nf_flow_offload_work_gc(struct work_struct *work)
        queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
 }
 
-int nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
-                                flow_setup_cb_t *cb, void *cb_priv)
-{
-       struct flow_block *block = &flow_table->flow_block;
-       struct flow_block_cb *block_cb;
-       int err = 0;
-
-       down_write(&flow_table->flow_block_lock);
-       block_cb = flow_block_cb_lookup(block, cb, cb_priv);
-       if (block_cb) {
-               err = -EEXIST;
-               goto unlock;
-       }
-
-       block_cb = flow_block_cb_alloc(cb, cb_priv, cb_priv, NULL);
-       if (IS_ERR(block_cb)) {
-               err = PTR_ERR(block_cb);
-               goto unlock;
-       }
-
-       list_add_tail(&block_cb->list, &block->cb_list);
-
-unlock:
-       up_write(&flow_table->flow_block_lock);
-       return err;
-}
-EXPORT_SYMBOL_GPL(nf_flow_table_offload_add_cb);
-
-void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
-                                 flow_setup_cb_t *cb, void *cb_priv)
-{
-       struct flow_block *block = &flow_table->flow_block;
-       struct flow_block_cb *block_cb;
-
-       down_write(&flow_table->flow_block_lock);
-       block_cb = flow_block_cb_lookup(block, cb, cb_priv);
-       if (block_cb) {
-               list_del(&block_cb->list);
-               flow_block_cb_free(block_cb);
-       } else {
-               WARN_ON(true);
-       }
-       up_write(&flow_table->flow_block_lock);
-}
-EXPORT_SYMBOL_GPL(nf_flow_table_offload_del_cb);
 
 static int nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
                                __be16 port, __be16 new_port)
index 073aa10..7647ecf 100644 (file)
@@ -6550,12 +6550,22 @@ err1:
        return err;
 }
 
+static void nft_flowtable_hook_release(struct nft_flowtable_hook *flowtable_hook)
+{
+       struct nft_hook *this, *next;
+
+       list_for_each_entry_safe(this, next, &flowtable_hook->list, list) {
+               list_del(&this->list);
+               kfree(this);
+       }
+}
+
 static int nft_delflowtable_hook(struct nft_ctx *ctx,
                                 struct nft_flowtable *flowtable)
 {
        const struct nlattr * const *nla = ctx->nla;
        struct nft_flowtable_hook flowtable_hook;
-       struct nft_hook *this, *next, *hook;
+       struct nft_hook *this, *hook;
        struct nft_trans *trans;
        int err;
 
@@ -6564,33 +6574,40 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
        if (err < 0)
                return err;
 
-       list_for_each_entry_safe(this, next, &flowtable_hook.list, list) {
+       list_for_each_entry(this, &flowtable_hook.list, list) {
                hook = nft_hook_list_find(&flowtable->hook_list, this);
                if (!hook) {
                        err = -ENOENT;
                        goto err_flowtable_del_hook;
                }
                hook->inactive = true;
-               list_del(&this->list);
-               kfree(this);
        }
 
        trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
                                sizeof(struct nft_trans_flowtable));
-       if (!trans)
-               return -ENOMEM;
+       if (!trans) {
+               err = -ENOMEM;
+               goto err_flowtable_del_hook;
+       }
 
        nft_trans_flowtable(trans) = flowtable;
        nft_trans_flowtable_update(trans) = true;
        INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
+       nft_flowtable_hook_release(&flowtable_hook);
 
        list_add_tail(&trans->list, &ctx->net->nft.commit_list);
 
        return 0;
 
 err_flowtable_del_hook:
-       list_for_each_entry(hook, &flowtable_hook.list, list)
+       list_for_each_entry(this, &flowtable_hook.list, list) {
+               hook = nft_hook_list_find(&flowtable->hook_list, this);
+               if (!hook)
+                       break;
+
                hook->inactive = false;
+       }
+       nft_flowtable_hook_release(&flowtable_hook);
 
        return err;
 }
index 8b5acc6..8c04388 100644 (file)
@@ -1242,7 +1242,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
                end += NFT_PIPAPO_GROUPS_PADDED_SIZE(f);
        }
 
-       if (!*this_cpu_ptr(m->scratch) || bsize_max > m->bsize_max) {
+       if (!*get_cpu_ptr(m->scratch) || bsize_max > m->bsize_max) {
+               put_cpu_ptr(m->scratch);
+
                err = pipapo_realloc_scratch(m, bsize_max);
                if (err)
                        return err;
@@ -1250,6 +1252,8 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
                this_cpu_write(nft_pipapo_scratch_index, false);
 
                m->bsize_max = bsize_max;
+       } else {
+               put_cpu_ptr(m->scratch);
        }
 
        *ext2 = &e->ext;
index 62f416b..b6aad3f 100644 (file)
@@ -271,12 +271,14 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
 
                        if (nft_rbtree_interval_start(new)) {
                                if (nft_rbtree_interval_end(rbe) &&
-                                   nft_set_elem_active(&rbe->ext, genmask))
+                                   nft_set_elem_active(&rbe->ext, genmask) &&
+                                   !nft_set_elem_expired(&rbe->ext))
                                        overlap = false;
                        } else {
                                overlap = nft_rbtree_interval_end(rbe) &&
                                          nft_set_elem_active(&rbe->ext,
-                                                             genmask);
+                                                             genmask) &&
+                                         !nft_set_elem_expired(&rbe->ext);
                        }
                } else if (d > 0) {
                        p = &parent->rb_right;
@@ -284,9 +286,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
                        if (nft_rbtree_interval_end(new)) {
                                overlap = nft_rbtree_interval_end(rbe) &&
                                          nft_set_elem_active(&rbe->ext,
-                                                             genmask);
+                                                             genmask) &&
+                                         !nft_set_elem_expired(&rbe->ext);
                        } else if (nft_rbtree_interval_end(rbe) &&
-                                  nft_set_elem_active(&rbe->ext, genmask)) {
+                                  nft_set_elem_active(&rbe->ext, genmask) &&
+                                  !nft_set_elem_expired(&rbe->ext)) {
                                overlap = true;
                        }
                } else {
@@ -294,15 +298,18 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
                            nft_rbtree_interval_start(new)) {
                                p = &parent->rb_left;
 
-                               if (nft_set_elem_active(&rbe->ext, genmask))
+                               if (nft_set_elem_active(&rbe->ext, genmask) &&
+                                   !nft_set_elem_expired(&rbe->ext))
                                        overlap = false;
                        } else if (nft_rbtree_interval_start(rbe) &&
                                   nft_rbtree_interval_end(new)) {
                                p = &parent->rb_right;
 
-                               if (nft_set_elem_active(&rbe->ext, genmask))
+                               if (nft_set_elem_active(&rbe->ext, genmask) &&
+                                   !nft_set_elem_expired(&rbe->ext))
                                        overlap = false;
-                       } else if (nft_set_elem_active(&rbe->ext, genmask)) {
+                       } else if (nft_set_elem_active(&rbe->ext, genmask) &&
+                                  !nft_set_elem_expired(&rbe->ext)) {
                                *ext = &rbe->ext;
                                return -EEXIST;
                        } else {
index 5ae069d..8dfff43 100644 (file)
@@ -264,7 +264,13 @@ struct rds_ib_device {
        int                     *vector_load;
 };
 
-#define ibdev_to_node(ibdev) dev_to_node((ibdev)->dev.parent)
+static inline int ibdev_to_node(struct ib_device *ibdev)
+{
+       struct device *parent;
+
+       parent = ibdev->dev.parent;
+       return parent ? dev_to_node(parent) : NUMA_NO_NODE;
+}
 #define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev)
 
 /* bits for i_ack_flags */
index e29f0f4..e9f3576 100644 (file)
@@ -1543,17 +1543,6 @@ static void __exit ct_cleanup_module(void)
        destroy_workqueue(act_ct_wq);
 }
 
-void tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie)
-{
-       enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK;
-       struct nf_conn *ct;
-
-       ct = (struct nf_conn *)(cookie & NFCT_PTRMASK);
-       nf_conntrack_get(&ct->ct_general);
-       nf_ct_set(skb, ct, ctinfo);
-}
-EXPORT_SYMBOL_GPL(tcf_ct_flow_table_restore_skb);
-
 module_init(ct_init_module);
 module_exit(ct_cleanup_module);
 MODULE_AUTHOR("Paul Blakey <paulb@mellanox.com>");
index f3ac549..0ed6e4d 100644 (file)
@@ -211,7 +211,7 @@ config SAMPLE_WATCHDOG
 
 config SAMPLE_WATCH_QUEUE
        bool "Build example /dev/watch_queue notification consumer"
-       depends on HEADERS_INSTALL
+       depends on CC_CAN_LINK && HEADERS_INSTALL
        help
          Build example userspace program to use the new mount_notify(),
          sb_notify() syscalls and the KEYCTL_WATCH_KEY keyctl() function.
index d523450..6aba02a 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/timer.h>
 #include <linux/err.h>
 #include <linux/jiffies.h>
+#include <linux/workqueue.h>
 
 /*
  * Any file that uses trace points, must include the header.
@@ -20,6 +21,16 @@ struct trace_array *tr;
 static void mytimer_handler(struct timer_list *unused);
 static struct task_struct *simple_tsk;
 
+static void trace_work_fn(struct work_struct *work)
+{
+       /*
+        * Disable tracing for event "sample_event".
+        */
+       trace_array_set_clr_event(tr, "sample-subsystem", "sample_event",
+                       false);
+}
+static DECLARE_WORK(trace_work, trace_work_fn);
+
 /*
  * mytimer: Timer setup to disable tracing for event "sample_event". This
  * timer is only for the purposes of the sample module to demonstrate access of
@@ -29,11 +40,7 @@ static DEFINE_TIMER(mytimer, mytimer_handler);
 
 static void mytimer_handler(struct timer_list *unused)
 {
-       /*
-        * Disable tracing for event "sample_event".
-        */
-       trace_array_set_clr_event(tr, "sample-subsystem", "sample_event",
-                       false);
+       schedule_work(&trace_work);
 }
 
 static void simple_thread_func(int count)
@@ -76,6 +83,7 @@ static int simple_thread(void *arg)
                simple_thread_func(count++);
 
        del_timer(&mytimer);
+       cancel_work_sync(&trace_work);
 
        /*
         * trace_array_put() decrements the reference counter associated with
@@ -107,8 +115,12 @@ static int __init sample_trace_array_init(void)
        trace_printk_init_buffers();
 
        simple_tsk = kthread_run(simple_thread, NULL, "sample-instance");
-       if (IS_ERR(simple_tsk))
+       if (IS_ERR(simple_tsk)) {
+               trace_array_put(tr);
+               trace_array_destroy(tr);
                return -1;
+       }
+
        return 0;
 }
 
index 3223448..ad3e560 100644 (file)
@@ -267,7 +267,7 @@ struct amt_host_if_msg_header {
 struct amt_host_if_resp_header {
        struct amt_host_if_msg_header header;
        uint32_t status;
-       unsigned char data[0];
+       unsigned char data[];
 } __attribute__((packed));
 
 const uuid_le MEI_IAMTHIF = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,  \
index 8511fb6..792b22f 100644 (file)
@@ -1,7 +1,5 @@
-# List of programs to build
-hostprogs := watch_test
+# SPDX-License-Identifier: GPL-2.0-only
+userprogs := watch_test
+always-y := $(userprogs)
 
-# Tell kbuild to always build the programs
-always-y := $(hostprogs)
-
-HOSTCFLAGS_watch_test.o += -I$(objtree)/usr/include
+userccflags += -I usr/include
index 0c3dc98..9a15fbf 100644 (file)
@@ -86,20 +86,21 @@ cc-cross-prefix = $(firstword $(foreach c, $(1), \
                        $(if $(shell command -v -- $(c)gcc 2>/dev/null), $(c))))
 
 # output directory for tests below
-TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
+TMPOUT = $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_$$$$
 
 # try-run
 # Usage: option = $(call try-run, $(CC)...-o "$$TMP",option-ok,otherwise)
 # Exit code chooses option. "$$TMP" serves as a temporary file and is
 # automatically cleaned up.
 try-run = $(shell set -e;              \
-       TMP="$(TMPOUT).$$$$.tmp";       \
-       TMPO="$(TMPOUT).$$$$.o";        \
+       TMP=$(TMPOUT)/tmp;              \
+       TMPO=$(TMPOUT)/tmp.o;           \
+       mkdir -p $(TMPOUT);             \
+       trap "rm -rf $(TMPOUT)" EXIT;   \
        if ($(1)) >/dev/null 2>&1;      \
        then echo "$(2)";               \
        else echo "$(3)";               \
-       fi;                             \
-       rm -f "$$TMP" "$$TMPO")
+       fi)
 
 # as-option
 # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
index c264da2..a5fe72c 100644 (file)
@@ -25,18 +25,12 @@ failure = $(if-success,$(1),n,y)
 
 # $(cc-option,<flag>)
 # Return y if the compiler supports <flag>, n otherwise
-cc-option = $(success,$(CC) -Werror $(CLANG_FLAGS) $(1) -S -x c /dev/null -o /dev/null)
+cc-option = $(success,mkdir .tmp_$$$$; trap "rm -rf .tmp_$$$$" EXIT; $(CC) -Werror $(CLANG_FLAGS) $(1) -c -x c /dev/null -o .tmp_$$$$/tmp.o)
 
 # $(ld-option,<flag>)
 # Return y if the linker supports <flag>, n otherwise
 ld-option = $(success,$(LD) -v $(1))
 
-# $(as-option,<flag>)
-# /dev/zero is used as output instead of /dev/null as some assembler cribs when
-# both input and output are same. Also both of them have same write behaviour so
-# can be easily substituted.
-as-option = $(success, $(CC) $(CLANG_FLAGS) $(1) -c -x assembler /dev/null -o /dev/zero)
-
 # $(as-instr,<instr>)
 # Return y if the assembler supports <instr>, n otherwise
 as-instr = $(success,printf "%b\n" "$(1)" | $(CC) $(CLANG_FLAGS) -c -x assembler -o /dev/null -)
index 13e5fba..66a6d51 100755 (executable)
@@ -27,7 +27,10 @@ parse_symbol() {
        elif [[ "${modcache[$module]+isset}" == "isset" ]]; then
                local objfile=${modcache[$module]}
        else
-               [[ $modpath == "" ]] && return
+               if [[ $modpath == "" ]]; then
+                       echo "WARNING! Modules path isn't set, but is needed to parse this symbol" >&2
+                       return
+               fi
                local objfile=$(find "$modpath" -name "${module//_/[-_]}.ko*" -print -quit)
                [[ $objfile == "" ]] && return
                modcache[$module]=$objfile
index 955cf3a..224f510 100755 (executable)
@@ -11,7 +11,7 @@ then
        echo "asm/inline/volatile keywords."
        echo
        echo "INFILE: header file to operate on"
-       echo "OUTFILE: output file which the processed header is writen to"
+       echo "OUTFILE: output file which the processed header is written to"
 
        exit 1
 fi
index 74eab03..f9b1952 100644 (file)
 #undef has_rel_mcount
 #undef tot_relsize
 #undef get_mcountsym
+#undef find_symtab
+#undef get_shnum
+#undef set_shnum
+#undef get_shstrndx
+#undef get_symindex
 #undef get_sym_str_and_relp
 #undef do_func
 #undef Elf_Addr
 # define __has_rel_mcount      __has64_rel_mcount
 # define has_rel_mcount                has64_rel_mcount
 # define tot_relsize           tot64_relsize
+# define find_symtab           find_symtab64
+# define get_shnum             get_shnum64
+# define set_shnum             set_shnum64
+# define get_shstrndx          get_shstrndx64
+# define get_symindex          get_symindex64
 # define get_sym_str_and_relp  get_sym_str_and_relp_64
 # define do_func               do64
 # define get_mcountsym         get_mcountsym_64
 # define __has_rel_mcount      __has32_rel_mcount
 # define has_rel_mcount                has32_rel_mcount
 # define tot_relsize           tot32_relsize
+# define find_symtab           find_symtab32
+# define get_shnum             get_shnum32
+# define set_shnum             set_shnum32
+# define get_shstrndx          get_shstrndx32
+# define get_symindex          get_symindex32
 # define get_sym_str_and_relp  get_sym_str_and_relp_32
 # define do_func               do32
 # define get_mcountsym         get_mcountsym_32
@@ -173,6 +188,67 @@ static int MIPS_is_fake_mcount(Elf_Rel const *rp)
        return is_fake;
 }
 
+static unsigned int get_symindex(Elf_Sym const *sym, Elf32_Word const *symtab,
+                                Elf32_Word const *symtab_shndx)
+{
+       unsigned long offset;
+       int index;
+
+       if (sym->st_shndx != SHN_XINDEX)
+               return w2(sym->st_shndx);
+
+       offset = (unsigned long)sym - (unsigned long)symtab;
+       index = offset / sizeof(*sym);
+
+       return w(symtab_shndx[index]);
+}
+
+static unsigned int get_shnum(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
+{
+       if (shdr0 && !ehdr->e_shnum)
+               return w(shdr0->sh_size);
+
+       return w2(ehdr->e_shnum);
+}
+
+static void set_shnum(Elf_Ehdr *ehdr, Elf_Shdr *shdr0, unsigned int new_shnum)
+{
+       if (new_shnum >= SHN_LORESERVE) {
+               ehdr->e_shnum = 0;
+               shdr0->sh_size = w(new_shnum);
+       } else
+               ehdr->e_shnum = w2(new_shnum);
+}
+
+static int get_shstrndx(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
+{
+       if (ehdr->e_shstrndx != SHN_XINDEX)
+               return w2(ehdr->e_shstrndx);
+
+       return w(shdr0->sh_link);
+}
+
+static void find_symtab(Elf_Ehdr *const ehdr, Elf_Shdr const *shdr0,
+                       unsigned const nhdr, Elf32_Word **symtab,
+                       Elf32_Word **symtab_shndx)
+{
+       Elf_Shdr const *relhdr;
+       unsigned k;
+
+       *symtab = NULL;
+       *symtab_shndx = NULL;
+
+       for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
+               if (relhdr->sh_type == SHT_SYMTAB)
+                       *symtab = (void *)ehdr + relhdr->sh_offset;
+               else if (relhdr->sh_type == SHT_SYMTAB_SHNDX)
+                       *symtab_shndx = (void *)ehdr + relhdr->sh_offset;
+
+               if (*symtab && *symtab_shndx)
+                       break;
+       }
+}
+
 /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
 static int append_func(Elf_Ehdr *const ehdr,
                        Elf_Shdr *const shstr,
@@ -188,10 +264,12 @@ static int append_func(Elf_Ehdr *const ehdr,
        char const *mc_name = (sizeof(Elf_Rela) == rel_entsize)
                ? ".rela__mcount_loc"
                :  ".rel__mcount_loc";
-       unsigned const old_shnum = w2(ehdr->e_shnum);
        uint_t const old_shoff = _w(ehdr->e_shoff);
        uint_t const old_shstr_sh_size   = _w(shstr->sh_size);
        uint_t const old_shstr_sh_offset = _w(shstr->sh_offset);
+       Elf_Shdr *const shdr0 = (Elf_Shdr *)(old_shoff + (void *)ehdr);
+       unsigned int const old_shnum = get_shnum(ehdr, shdr0);
+       unsigned int const new_shnum = 2 + old_shnum; /* {.rel,}__mcount_loc */
        uint_t t = 1 + strlen(mc_name) + _w(shstr->sh_size);
        uint_t new_e_shoff;
 
@@ -201,6 +279,8 @@ static int append_func(Elf_Ehdr *const ehdr,
        t += (_align & -t);  /* word-byte align */
        new_e_shoff = t;
 
+       set_shnum(ehdr, shdr0, new_shnum);
+
        /* body for new shstrtab */
        if (ulseek(sb.st_size, SEEK_SET) < 0)
                return -1;
@@ -255,7 +335,6 @@ static int append_func(Elf_Ehdr *const ehdr,
                return -1;
 
        ehdr->e_shoff = _w(new_e_shoff);
-       ehdr->e_shnum = w2(2 + w2(ehdr->e_shnum));  /* {.rel,}__mcount_loc */
        if (ulseek(0, SEEK_SET) < 0)
                return -1;
        if (uwrite(ehdr, sizeof(*ehdr)) < 0)
@@ -434,6 +513,8 @@ static int find_secsym_ndx(unsigned const txtndx,
                                uint_t *const recvalp,
                                unsigned int *sym_index,
                                Elf_Shdr const *const symhdr,
+                               Elf32_Word const *symtab,
+                               Elf32_Word const *symtab_shndx,
                                Elf_Ehdr const *const ehdr)
 {
        Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symhdr->sh_offset)
@@ -445,7 +526,7 @@ static int find_secsym_ndx(unsigned const txtndx,
        for (symp = sym0, t = nsym; t; --t, ++symp) {
                unsigned int const st_bind = ELF_ST_BIND(symp->st_info);
 
-               if (txtndx == w2(symp->st_shndx)
+               if (txtndx == get_symindex(symp, symtab, symtab_shndx)
                        /* avoid STB_WEAK */
                    && (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
                        /* function symbols on ARM have quirks, avoid them */
@@ -516,21 +597,23 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0,
        return totrelsz;
 }
 
-
 /* Overall supervision for Elf32 ET_REL file. */
 static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
                   unsigned const reltype)
 {
        Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
                + (void *)ehdr);
-       unsigned const nhdr = w2(ehdr->e_shnum);
-       Elf_Shdr *const shstr = &shdr0[w2(ehdr->e_shstrndx)];
+       unsigned const nhdr = get_shnum(ehdr, shdr0);
+       Elf_Shdr *const shstr = &shdr0[get_shstrndx(ehdr, shdr0)];
        char const *const shstrtab = (char const *)(_w(shstr->sh_offset)
                + (void *)ehdr);
 
        Elf_Shdr const *relhdr;
        unsigned k;
 
+       Elf32_Word *symtab;
+       Elf32_Word *symtab_shndx;
+
        /* Upper bound on space: assume all relevant relocs are for mcount. */
        unsigned       totrelsz;
 
@@ -561,6 +644,8 @@ static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
                return -1;
        }
 
+       find_symtab(ehdr, shdr0, nhdr, &symtab, &symtab_shndx);
+
        for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
                char const *const txtname = has_rel_mcount(relhdr, shdr0,
                        shstrtab, fname);
@@ -577,6 +662,7 @@ static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
                        result = find_secsym_ndx(w(relhdr->sh_info), txtname,
                                                &recval, &recsym,
                                                &shdr0[symsec_sh_link],
+                                               symtab, symtab_shndx,
                                                ehdr);
                        if (result)
                                goto out;
index 298b737..16c1894 100644 (file)
@@ -107,7 +107,7 @@ struct ima_digest_data {
                } ng;
                u8 data[2];
        } xattr;
-       u8 digest[0];
+       u8 digest[];
 } __packed;
 
 /*
@@ -119,7 +119,7 @@ struct signature_v2_hdr {
        uint8_t hash_algo;      /* Digest algorithm [enum hash_algo] */
        __be32 keyid;           /* IMA key identifier - not X509/PGP specific */
        __be16 sig_size;        /* signature size */
-       uint8_t sig[0];         /* signature payload */
+       uint8_t sig[];          /* signature payload */
 } __packed;
 
 /* integrity data associated with an inode */
index da94a1b..0cc7cdd 100644 (file)
@@ -27,6 +27,9 @@ static int cond_evaluate_expr(struct policydb *p, struct cond_expr *expr)
        int s[COND_EXPR_MAXDEPTH];
        int sp = -1;
 
+       if (expr->len == 0)
+               return -1;
+
        for (i = 0; i < expr->len; i++) {
                struct cond_expr_node *node = &expr->nodes[i];
 
@@ -392,27 +395,19 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
 
                rc = next_entry(buf, fp, sizeof(u32) * 2);
                if (rc)
-                       goto err;
+                       return rc;
 
                expr->expr_type = le32_to_cpu(buf[0]);
                expr->bool = le32_to_cpu(buf[1]);
 
-               if (!expr_node_isvalid(p, expr)) {
-                       rc = -EINVAL;
-                       goto err;
-               }
+               if (!expr_node_isvalid(p, expr))
+                       return -EINVAL;
        }
 
        rc = cond_read_av_list(p, fp, &node->true_list, NULL);
        if (rc)
-               goto err;
-       rc = cond_read_av_list(p, fp, &node->false_list, &node->true_list);
-       if (rc)
-               goto err;
-       return 0;
-err:
-       cond_node_destroy(node);
-       return rc;
+               return rc;
+       return cond_read_av_list(p, fp, &node->false_list, &node->true_list);
 }
 
 int cond_read_list(struct policydb *p, void *fp)
index 313919b..ef0afd8 100644 (file)
@@ -2888,8 +2888,12 @@ err:
        if (*names) {
                for (i = 0; i < *len; i++)
                        kfree((*names)[i]);
+               kfree(*names);
        }
        kfree(*values);
+       *len = 0;
+       *names = NULL;
+       *values = NULL;
        goto out;
 }
 
index b04b728..5e159ab 100644 (file)
@@ -36,7 +36,7 @@ struct sof_probe_point_desc {
 struct sof_ipc_probe_dma_add_params {
        struct sof_ipc_cmd_hdr hdr;
        unsigned int num_elems;
-       struct sof_probe_dma dma[0];
+       struct sof_probe_dma dma[];
 } __packed;
 
 struct sof_ipc_probe_info_params {
@@ -51,19 +51,19 @@ struct sof_ipc_probe_info_params {
 struct sof_ipc_probe_dma_remove_params {
        struct sof_ipc_cmd_hdr hdr;
        unsigned int num_elems;
-       unsigned int stream_tag[0];
+       unsigned int stream_tag[];
 } __packed;
 
 struct sof_ipc_probe_point_add_params {
        struct sof_ipc_cmd_hdr hdr;
        unsigned int num_elems;
-       struct sof_probe_point_desc desc[0];
+       struct sof_probe_point_desc desc[];
 } __packed;
 
 struct sof_ipc_probe_point_remove_params {
        struct sof_ipc_cmd_hdr hdr;
        unsigned int num_elems;
-       unsigned int buffer_id[0];
+       unsigned int buffer_id[];
 } __packed;
 
 int sof_ipc_probe_init(struct snd_sof_dev *sdev,
index db18994..02dabc9 100644 (file)
 #define X86_FEATURE_AVX512_4FMAPS      (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
 #define X86_FEATURE_FSRM               (18*32+ 4) /* Fast Short Rep Mov */
 #define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* AVX-512 Intersect for D/Q */
+#define X86_FEATURE_SRBDS_CTRL         (18*32+ 9) /* "" SRBDS mitigation MSR available */
 #define X86_FEATURE_MD_CLEAR           (18*32+10) /* VERW clears CPU buffers */
 #define X86_FEATURE_TSX_FORCE_ABORT    (18*32+13) /* "" TSX_FORCE_ABORT */
 #define X86_FEATURE_PCONFIG            (18*32+18) /* Intel PCONFIG */
 #define X86_BUG_SWAPGS                 X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
 #define X86_BUG_TAA                    X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */
 #define X86_BUG_ITLB_MULTIHIT          X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
+#define X86_BUG_SRBDS                  X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
index ef452b8..e8370e6 100644 (file)
 #define TSX_CTRL_RTM_DISABLE           BIT(0)  /* Disable RTM feature */
 #define TSX_CTRL_CPUID_CLEAR           BIT(1)  /* Disable TSX enumeration */
 
+/* SRBDS support */
+#define MSR_IA32_MCU_OPT_CTRL          0x00000123
+#define RNGDS_MITG_DIS                 BIT(0)
+
 #define MSR_IA32_SYSENTER_CS           0x00000174
 #define MSR_IA32_SYSENTER_ESP          0x00000175
 #define MSR_IA32_SYSENTER_EIP          0x00000176
index 43e2490..17c5a03 100644 (file)
@@ -385,33 +385,48 @@ struct kvm_sync_regs {
 #define KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT (1 << 4)
 
 #define KVM_STATE_NESTED_FORMAT_VMX    0
-#define KVM_STATE_NESTED_FORMAT_SVM    1       /* unused */
+#define KVM_STATE_NESTED_FORMAT_SVM    1
 
 #define KVM_STATE_NESTED_GUEST_MODE    0x00000001
 #define KVM_STATE_NESTED_RUN_PENDING   0x00000002
 #define KVM_STATE_NESTED_EVMCS         0x00000004
 #define KVM_STATE_NESTED_MTF_PENDING   0x00000008
+#define KVM_STATE_NESTED_GIF_SET       0x00000100
 
 #define KVM_STATE_NESTED_SMM_GUEST_MODE        0x00000001
 #define KVM_STATE_NESTED_SMM_VMXON     0x00000002
 
 #define KVM_STATE_NESTED_VMX_VMCS_SIZE 0x1000
 
+#define KVM_STATE_NESTED_SVM_VMCB_SIZE 0x1000
+
+#define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE        0x00000001
+
 struct kvm_vmx_nested_state_data {
        __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
        __u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
-       __u64 preemption_timer_deadline;
 };
 
 struct kvm_vmx_nested_state_hdr {
+       __u32 flags;
        __u64 vmxon_pa;
        __u64 vmcs12_pa;
+       __u64 preemption_timer_deadline;
 
        struct {
                __u16 flags;
        } smm;
 };
 
+struct kvm_svm_nested_state_data {
+       /* Save area only used if KVM_STATE_NESTED_RUN_PENDING.  */
+       __u8 vmcb12[KVM_STATE_NESTED_SVM_VMCB_SIZE];
+};
+
+struct kvm_svm_nested_state_hdr {
+       __u64 vmcb_pa;
+};
+
 /* for KVM_CAP_NESTED_STATE */
 struct kvm_nested_state {
        __u16 flags;
@@ -420,6 +435,7 @@ struct kvm_nested_state {
 
        union {
                struct kvm_vmx_nested_state_hdr vmx;
+               struct kvm_svm_nested_state_hdr svm;
 
                /* Pad the header to 128 bytes.  */
                __u8 pad[120];
@@ -432,6 +448,7 @@ struct kvm_nested_state {
         */
        union {
                struct kvm_vmx_nested_state_data vmx[0];
+               struct kvm_svm_nested_state_data svm[0];
        } data;
 };
 
index 30d7d04..be5e2e7 100644 (file)
@@ -2,7 +2,14 @@
 #ifndef _UAPI_ASM_X86_UNISTD_H
 #define _UAPI_ASM_X86_UNISTD_H
 
-/* x32 syscall flag bit */
+/*
+ * x32 syscall flag bit.  Some user programs expect syscall NR macros
+ * and __X32_SYSCALL_BIT to have type int, even though syscall numbers
+ * are, for practical purposes, unsigned long.
+ *
+ * Fortunately, expressions like (nr & ~__X32_SYSCALL_BIT) do the right
+ * thing regardless.
+ */
 #define __X32_SYSCALL_BIT      0x40000000
 
 #ifndef __KERNEL__
index e95b72e..b8ff9e8 100644 (file)
        { EXIT_REASON_UMWAIT,                "UMWAIT" }, \
        { EXIT_REASON_TPAUSE,                "TPAUSE" }
 
+#define VMX_EXIT_REASON_FLAGS \
+       { VMX_EXIT_REASONS_FAILED_VMENTRY,      "FAILED_VMENTRY" }
+
 #define VMX_ABORT_SAVE_GUEST_MSR_FAIL        1
 #define VMX_ABORT_LOAD_HOST_PDPTE_FAIL       2
 #define VMX_ABORT_LOAD_HOST_MSR_FAIL         4
index 0efaf45..e0878f5 100644 (file)
 #include <linux/kernel.h>
 #include <linux/bootconfig.h>
 
-static int xbc_show_array(struct xbc_node *node)
+static int xbc_show_value(struct xbc_node *node)
 {
        const char *val;
+       char q;
        int i = 0;
 
        xbc_array_for_each_value(node, val) {
-               printf("\"%s\"%s", val, node->next ? ", " : ";\n");
+               if (strchr(val, '"'))
+                       q = '\'';
+               else
+                       q = '"';
+               printf("%c%s%c%s", q, val, q, node->next ? ", " : ";\n");
                i++;
        }
        return i;
@@ -48,10 +53,7 @@ static void xbc_show_compact_tree(void)
                        continue;
                } else if (cnode && xbc_node_is_value(cnode)) {
                        printf("%s = ", xbc_node_get_data(node));
-                       if (cnode->next)
-                               xbc_show_array(cnode);
-                       else
-                               printf("\"%s\";\n", xbc_node_get_data(cnode));
+                       xbc_show_value(cnode);
                } else {
                        printf("%s;\n", xbc_node_get_data(node));
                }
@@ -205,11 +207,13 @@ int show_xbc(const char *path)
        }
 
        ret = load_xbc_from_initrd(fd, &buf);
-       if (ret < 0)
+       if (ret < 0) {
                pr_err("Failed to load a boot config from initrd: %d\n", ret);
-       else
-               xbc_show_compact_tree();
-
+               goto out;
+       }
+       xbc_show_compact_tree();
+       ret = 0;
+out:
        close(fd);
        free(buf);
 
index eff16b7..3c2ab9e 100755 (executable)
@@ -55,6 +55,9 @@ echo "Apply command test"
 xpass $BOOTCONF -a $TEMPCONF $INITRD
 new_size=$(stat -c %s $INITRD)
 
+echo "Show command test"
+xpass $BOOTCONF $INITRD
+
 echo "File size check"
 xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9 + 12)
 
@@ -114,6 +117,13 @@ xpass grep -q "bar" $OUTFILE
 xpass grep -q "baz" $OUTFILE
 xpass grep -q "qux" $OUTFILE
 
+echo "Double/single quotes test"
+echo "key = '\"string\"';" > $TEMPCONF
+$BOOTCONF -a $TEMPCONF $INITRD
+$BOOTCONF $INITRD > $TEMPCONF
+cat $TEMPCONF
+xpass grep \'\"string\"\' $TEMPCONF
+
 echo "=== expected failure cases ==="
 for i in samples/bad-* ; do
   xfail $BOOTCONF -a $i $INITRD
index 3a3201e..f4a0130 100644 (file)
@@ -855,9 +855,11 @@ __SYSCALL(__NR_clone3, sys_clone3)
 __SYSCALL(__NR_openat2, sys_openat2)
 #define __NR_pidfd_getfd 438
 __SYSCALL(__NR_pidfd_getfd, sys_pidfd_getfd)
+#define __NR_faccessat2 439
+__SYSCALL(__NR_faccessat2, sys_faccessat2)
 
 #undef __NR_syscalls
-#define __NR_syscalls 439
+#define __NR_syscalls 440
 
 /*
  * 32 bit systems traditionally used different
index 2813e57..14b67cd 100644 (file)
@@ -1969,6 +1969,30 @@ enum drm_i915_perf_property_id {
         */
        DRM_I915_PERF_PROP_HOLD_PREEMPTION,
 
+       /**
+        * Specifying this pins all contexts to the specified SSEU power
+        * configuration for the duration of the recording.
+        *
+        * This parameter's value is a pointer to a struct
+        * drm_i915_gem_context_param_sseu.
+        *
+        * This property is available in perf revision 4.
+        */
+       DRM_I915_PERF_PROP_GLOBAL_SSEU,
+
+       /**
+        * This optional parameter specifies the timer interval in nanoseconds
+        * at which the i915 driver will check the OA buffer for available data.
+        * Minimum allowed value is 100 microseconds. A default value is used by
+        * the driver if this parameter is not specified. Note that larger timer
+        * values will reduce cpu consumption during OA perf captures. However,
+        * excessively large values would potentially result in OA buffer
+        * overwrites as captures reach end of the OA buffer.
+        *
+        * This property is available in perf revision 5.
+        */
+       DRM_I915_PERF_PROP_POLL_OA_PERIOD,
+
        DRM_I915_PERF_PROP_MAX /* non-ABI */
 };
 
index ca88b7b..2f86b2a 100644 (file)
 #define DN_ATTRIB      0x00000020      /* File changed attibutes */
 #define DN_MULTISHOT   0x80000000      /* Don't remove notifier */
 
+/*
+ * The constants AT_REMOVEDIR and AT_EACCESS have the same value.  AT_EACCESS is
+ * meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to
+ * unlinkat.  The two functions do completely different things and therefore,
+ * the flags can be allowed to overlap.  For example, passing AT_REMOVEDIR to
+ * faccessat would be undefined behavior and thus treating it equivalent to
+ * AT_EACCESS is valid undefined behavior.
+ */
 #define AT_FDCWD               -100    /* Special value used to indicate
                                            openat should use the current
                                            working directory. */
 #define AT_SYMLINK_NOFOLLOW    0x100   /* Do not follow symbolic links.  */
+#define AT_EACCESS             0x200   /* Test access permitted for
+                                           effective IDs, not real IDs.  */
 #define AT_REMOVEDIR           0x200   /* Remove directory instead of
                                            unlinking file.  */
 #define AT_SYMLINK_FOLLOW      0x400   /* Follow symbolic links.  */
index 379a612..f44eb0a 100644 (file)
@@ -262,6 +262,7 @@ struct fsxattr {
 #define FS_EA_INODE_FL                 0x00200000 /* Inode used for large EA */
 #define FS_EOFBLOCKS_FL                        0x00400000 /* Reserved for ext4 */
 #define FS_NOCOW_FL                    0x00800000 /* Do not cow file */
+#define FS_DAX_FL                      0x02000000 /* Inode is DAX */
 #define FS_INLINE_DATA_FL              0x10000000 /* Reserved for ext4 */
 #define FS_PROJINHERIT_FL              0x20000000 /* Create with parents projid */
 #define FS_CASEFOLD_FL                 0x40000000 /* Folder is case insensitive */
index a10e3cd..7875709 100644 (file)
@@ -19,7 +19,8 @@
 #define FSCRYPT_POLICY_FLAGS_PAD_MASK          0x03
 #define FSCRYPT_POLICY_FLAG_DIRECT_KEY         0x04
 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64     0x08
-#define FSCRYPT_POLICY_FLAGS_VALID             0x0F
+#define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32     0x10
+#define FSCRYPT_POLICY_FLAGS_VALID             0x1F
 
 /* Encryption algorithms */
 #define FSCRYPT_MODE_AES_256_XTS               1
index fdd632c..4fdf303 100644 (file)
@@ -188,10 +188,13 @@ struct kvm_s390_cmma_log {
 struct kvm_hyperv_exit {
 #define KVM_EXIT_HYPERV_SYNIC          1
 #define KVM_EXIT_HYPERV_HCALL          2
+#define KVM_EXIT_HYPERV_SYNDBG         3
        __u32 type;
+       __u32 pad1;
        union {
                struct {
                        __u32 msr;
+                       __u32 pad2;
                        __u64 control;
                        __u64 evt_page;
                        __u64 msg_page;
@@ -201,6 +204,15 @@ struct kvm_hyperv_exit {
                        __u64 result;
                        __u64 params[2];
                } hcall;
+               struct {
+                       __u32 msr;
+                       __u32 pad2;
+                       __u64 control;
+                       __u64 status;
+                       __u64 send_page;
+                       __u64 recv_page;
+                       __u64 pending_page;
+               } syndbg;
        } u;
 };
 
@@ -1017,6 +1029,8 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_VCPU_RESETS 179
 #define KVM_CAP_S390_PROTECTED 180
 #define KVM_CAP_PPC_SECURE_GUEST 181
+#define KVM_CAP_HALT_POLL 182
+#define KVM_CAP_ASYNC_PF_INT 183
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index d119278..82cc58f 100644 (file)
@@ -123,7 +123,10 @@ struct statx {
        __u32   stx_dev_major;  /* ID of device containing file [uncond] */
        __u32   stx_dev_minor;
        /* 0x90 */
-       __u64   __spare2[14];   /* Spare space for future expansion */
+       __u64   stx_mnt_id;
+       __u64   __spare2;
+       /* 0xa0 */
+       __u64   __spare3[12];   /* Spare space for future expansion */
        /* 0x100 */
 };
 
@@ -148,6 +151,7 @@ struct statx {
 #define STATX_BLOCKS           0x00000400U     /* Want/got stx_blocks */
 #define STATX_BASIC_STATS      0x000007ffU     /* The stuff in the normal stat struct */
 #define STATX_BTIME            0x00000800U     /* Want/got stx_btime */
+#define STATX_MNT_ID           0x00001000U     /* Got stx_mnt_id */
 
 #define STATX__RESERVED                0x80000000U     /* Reserved for future struct statx expansion */
 
@@ -177,7 +181,9 @@ struct statx {
 #define STATX_ATTR_NODUMP              0x00000040 /* [I] File is not to be dumped */
 #define STATX_ATTR_ENCRYPTED           0x00000800 /* [I] File requires key to decrypt in fs */
 #define STATX_ATTR_AUTOMOUNT           0x00001000 /* Dir: Automount trigger */
+#define STATX_ATTR_MOUNT_ROOT          0x00002000 /* Root of a mount */
 #define STATX_ATTR_VERITY              0x00100000 /* [I] Verity protected file */
+#define STATX_ATTR_DAX                 0x00002000 /* [I] File is DAX */
 
 
 #endif /* _UAPI_LINUX_STAT_H */
index 9fe72e4..0c23496 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 
+#define VHOST_FILE_UNBIND -1
+
 /* ioctls */
 
 #define VHOST_VIRTIO 0xAF
 /* Get the max ring size. */
 #define VHOST_VDPA_GET_VRING_NUM       _IOR(VHOST_VIRTIO, 0x76, __u16)
 
+/* Set event fd for config interrupt*/
+#define VHOST_VDPA_SET_CONFIG_CALL     _IOW(VHOST_VIRTIO, 0x77, int)
 #endif
index e1bd2a9..5b36c58 100644 (file)
@@ -1425,13 +1425,28 @@ static unsigned int type_size(const char *name)
        return 0;
 }
 
+static int append(char **buf, const char *delim, const char *str)
+{
+       char *new_buf;
+
+       new_buf = realloc(*buf, strlen(*buf) + strlen(delim) + strlen(str) + 1);
+       if (!new_buf)
+               return -1;
+       strcat(new_buf, delim);
+       strcat(new_buf, str);
+       *buf = new_buf;
+       return 0;
+}
+
 static int event_read_fields(struct tep_event *event, struct tep_format_field **fields)
 {
        struct tep_format_field *field = NULL;
        enum tep_event_type type;
        char *token;
        char *last_token;
+       char *delim = " ";
        int count = 0;
+       int ret;
 
        do {
                unsigned int size_dynamic = 0;
@@ -1490,24 +1505,51 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
                                        field->flags |= TEP_FIELD_IS_POINTER;
 
                                if (field->type) {
-                                       char *new_type;
-                                       new_type = realloc(field->type,
-                                                          strlen(field->type) +
-                                                          strlen(last_token) + 2);
-                                       if (!new_type) {
-                                               free(last_token);
-                                               goto fail;
-                                       }
-                                       field->type = new_type;
-                                       strcat(field->type, " ");
-                                       strcat(field->type, last_token);
+                                       ret = append(&field->type, delim, last_token);
                                        free(last_token);
+                                       if (ret < 0)
+                                               goto fail;
                                } else
                                        field->type = last_token;
                                last_token = token;
+                               delim = " ";
                                continue;
                        }
 
+                       /* Handle __attribute__((user)) */
+                       if ((type == TEP_EVENT_DELIM) &&
+                           strcmp("__attribute__", last_token) == 0 &&
+                           token[0] == '(') {
+                               int depth = 1;
+                               int ret;
+
+                               ret = append(&field->type, " ", last_token);
+                               ret |= append(&field->type, "", "(");
+                               if (ret < 0)
+                                       goto fail;
+
+                               delim = " ";
+                               while ((type = read_token(&token)) != TEP_EVENT_NONE) {
+                                       if (type == TEP_EVENT_DELIM) {
+                                               if (token[0] == '(')
+                                                       depth++;
+                                               else if (token[0] == ')')
+                                                       depth--;
+                                               if (!depth)
+                                                       break;
+                                               ret = append(&field->type, "", token);
+                                               delim = "";
+                                       } else {
+                                               ret = append(&field->type, delim, token);
+                                               delim = " ";
+                                       }
+                                       if (ret < 0)
+                                               goto fail;
+                                       free(last_token);
+                                       last_token = token;
+                               }
+                               continue;
+                       }
                        break;
                }
 
@@ -1523,8 +1565,6 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
                if (strcmp(token, "[") == 0) {
                        enum tep_event_type last_type = type;
                        char *brackets = token;
-                       char *new_brackets;
-                       int len;
 
                        field->flags |= TEP_FIELD_IS_ARRAY;
 
@@ -1536,29 +1576,27 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
                                field->arraylen = 0;
 
                        while (strcmp(token, "]") != 0) {
+                               const char *delim;
+
                                if (last_type == TEP_EVENT_ITEM &&
                                    type == TEP_EVENT_ITEM)
-                                       len = 2;
+                                       delim = " ";
                                else
-                                       len = 1;
+                                       delim = "";
+
                                last_type = type;
 
-                               new_brackets = realloc(brackets,
-                                                      strlen(brackets) +
-                                                      strlen(token) + len);
-                               if (!new_brackets) {
+                               ret = append(&brackets, delim, token);
+                               if (ret < 0) {
                                        free(brackets);
                                        goto fail;
                                }
-                               brackets = new_brackets;
-                               if (len == 2)
-                                       strcat(brackets, " ");
-                               strcat(brackets, token);
                                /* We only care about the last token */
                                field->arraylen = strtoul(token, NULL, 0);
                                free_token(token);
                                type = read_token(&token);
                                if (type == TEP_EVENT_NONE) {
+                                       free(brackets);
                                        do_warning_event(event, "failed to find token");
                                        goto fail;
                                }
@@ -1566,13 +1604,11 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
 
                        free_token(token);
 
-                       new_brackets = realloc(brackets, strlen(brackets) + 2);
-                       if (!new_brackets) {
+                       ret = append(&brackets, "", "]");
+                       if (ret < 0) {
                                free(brackets);
                                goto fail;
                        }
-                       brackets = new_brackets;
-                       strcat(brackets, "]");
 
                        /* add brackets to type */
 
@@ -1582,34 +1618,23 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
                         * the format: type [] item;
                         */
                        if (type == TEP_EVENT_ITEM) {
-                               char *new_type;
-                               new_type = realloc(field->type,
-                                                  strlen(field->type) +
-                                                  strlen(field->name) +
-                                                  strlen(brackets) + 2);
-                               if (!new_type) {
+                               ret = append(&field->type, " ", field->name);
+                               if (ret < 0) {
                                        free(brackets);
                                        goto fail;
                                }
-                               field->type = new_type;
-                               strcat(field->type, " ");
-                               strcat(field->type, field->name);
+                               ret = append(&field->type, "", brackets);
+
                                size_dynamic = type_size(field->name);
                                free_token(field->name);
-                               strcat(field->type, brackets);
                                field->name = field->alias = token;
                                type = read_token(&token);
                        } else {
-                               char *new_type;
-                               new_type = realloc(field->type,
-                                                  strlen(field->type) +
-                                                  strlen(brackets) + 1);
-                               if (!new_type) {
+                               ret = append(&field->type, "", brackets);
+                               if (ret < 0) {
                                        free(brackets);
                                        goto fail;
                                }
-                               field->type = new_type;
-                               strcat(field->type, brackets);
                        }
                        free(brackets);
                }
@@ -2046,19 +2071,16 @@ process_op(struct tep_event *event, struct tep_print_arg *arg, char **tok)
                /* could just be a type pointer */
                if ((strcmp(arg->op.op, "*") == 0) &&
                    type == TEP_EVENT_DELIM && (strcmp(token, ")") == 0)) {
-                       char *new_atom;
+                       int ret;
 
                        if (left->type != TEP_PRINT_ATOM) {
                                do_warning_event(event, "bad pointer type");
                                goto out_free;
                        }
-                       new_atom = realloc(left->atom.atom,
-                                           strlen(left->atom.atom) + 3);
-                       if (!new_atom)
+                       ret = append(&left->atom.atom, " ", "*");
+                       if (ret < 0)
                                goto out_warn_free;
 
-                       left->atom.atom = new_atom;
-                       strcat(left->atom.atom, " *");
                        free(arg->op.op);
                        *arg = *left;
                        free(left);
@@ -3062,6 +3084,37 @@ err:
        return TEP_EVENT_ERROR;
 }
 
+static enum tep_event_type
+process_builtin_expect(struct tep_event *event, struct tep_print_arg *arg, char **tok)
+{
+       enum tep_event_type type;
+       char *token = NULL;
+
+       /* Handle __builtin_expect( cond, #) */
+       type = process_arg(event, arg, &token);
+
+       if (type != TEP_EVENT_DELIM || token[0] != ',')
+               goto out_free;
+
+       free_token(token);
+
+       /* We don't care what the second parameter is of the __builtin_expect() */
+       if (read_expect_type(TEP_EVENT_ITEM, &token) < 0)
+               goto out_free;
+
+       if (read_expected(TEP_EVENT_DELIM, ")") < 0)
+               goto out_free;
+
+       free_token(token);
+       type = read_token_item(tok);
+       return type;
+
+out_free:
+       free_token(token);
+       *tok = NULL;
+       return TEP_EVENT_ERROR;
+}
+
 static enum tep_event_type
 process_function(struct tep_event *event, struct tep_print_arg *arg,
                 char *token, char **tok)
@@ -3106,6 +3159,10 @@ process_function(struct tep_event *event, struct tep_print_arg *arg,
                free_token(token);
                return process_dynamic_array_len(event, arg, tok);
        }
+       if (strcmp(token, "__builtin_expect") == 0) {
+               free_token(token);
+               return process_builtin_expect(event, arg, tok);
+       }
 
        func = find_func_handler(event->tep, token);
        if (func) {
@@ -3151,18 +3208,15 @@ process_arg_token(struct tep_event *event, struct tep_print_arg *arg,
                }
                /* atoms can be more than one token long */
                while (type == TEP_EVENT_ITEM) {
-                       char *new_atom;
-                       new_atom = realloc(atom,
-                                          strlen(atom) + strlen(token) + 2);
-                       if (!new_atom) {
+                       int ret;
+
+                       ret = append(&atom, " ", token);
+                       if (ret < 0) {
                                free(atom);
                                *tok = NULL;
                                free_token(token);
                                return TEP_EVENT_ERROR;
                        }
-                       atom = new_atom;
-                       strcat(atom, " ");
-                       strcat(atom, token);
                        free_token(token);
                        type = read_token_item(&token);
                }
index 877ca6b..5136338 100644 (file)
@@ -396,6 +396,18 @@ else
       NO_LIBBPF := 1
       NO_JVMTI := 1
     else
+      ifneq ($(filter s% -fsanitize=address%,$(EXTRA_CFLAGS),),)
+        ifneq ($(shell ldconfig -p | grep libasan >/dev/null 2>&1; echo $$?), 0)
+          msg := $(error No libasan found, please install libasan);
+        endif
+      endif
+
+      ifneq ($(filter s% -fsanitize=undefined%,$(EXTRA_CFLAGS),),)
+        ifneq ($(shell ldconfig -p | grep libubsan >/dev/null 2>&1; echo $$?), 0)
+          msg := $(error No libubsan found, please install libubsan);
+        endif
+      endif
+
       ifneq ($(filter s% -static%,$(LDFLAGS),),)
         msg := $(error No static glibc found, please install glibc-static);
       else
index 37b844f..78847b3 100644 (file)
 435    common  clone3                  sys_clone3
 437    common  openat2                 sys_openat2
 438    common  pidfd_getfd             sys_pidfd_getfd
+439    common  faccessat2              sys_faccessat2
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
index b63b3fb..5f1d2a8 100644 (file)
@@ -478,8 +478,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
        if (rep->time_str)
                ret += fprintf(fp, " (time slices: %s)", rep->time_str);
 
-       if (symbol_conf.show_ref_callgraph &&
-           strstr(evname, "call-graph=no")) {
+       if (symbol_conf.show_ref_callgraph && evname && strstr(evname, "call-graph=no")) {
                ret += fprintf(fp, ", show reference callgraph");
        }
 
index 5da2436..181d65e 100644 (file)
@@ -3837,6 +3837,9 @@ int cmd_script(int argc, const char **argv)
        if (err)
                goto out_delete;
 
+       if (zstd_init(&(session->zstd_data), 0) < 0)
+               pr_warning("Decompression initialization failed. Reported data may be incomplete.\n");
+
        err = __cmd_script(&script);
 
        flush_scripting();
index 811cc0e..110f0c6 100644 (file)
@@ -65,6 +65,7 @@ size_t syscall_arg__scnprintf_statx_mask(char *bf, size_t size, struct syscall_a
        P_FLAG(SIZE);
        P_FLAG(BLOCKS);
        P_FLAG(BTIME);
+       P_FLAG(MNT_ID);
 
 #undef P_FLAG
 
index b020a86..9887ae0 100644 (file)
@@ -142,7 +142,8 @@ static int
 gen_read_mem(struct bpf_insn_pos *pos,
             int src_base_addr_reg,
             int dst_addr_reg,
-            long offset)
+            long offset,
+            int probeid)
 {
        /* mov arg3, src_base_addr_reg */
        if (src_base_addr_reg != BPF_REG_ARG3)
@@ -159,7 +160,7 @@ gen_read_mem(struct bpf_insn_pos *pos,
                ins(BPF_MOV64_REG(BPF_REG_ARG1, dst_addr_reg), pos);
 
        /* Call probe_read  */
-       ins(BPF_EMIT_CALL(BPF_FUNC_probe_read), pos);
+       ins(BPF_EMIT_CALL(probeid), pos);
        /*
         * Error processing: if read fail, goto error code,
         * will be relocated. Target should be the start of
@@ -241,7 +242,7 @@ static int
 gen_prologue_slowpath(struct bpf_insn_pos *pos,
                      struct probe_trace_arg *args, int nargs)
 {
-       int err, i;
+       int err, i, probeid;
 
        for (i = 0; i < nargs; i++) {
                struct probe_trace_arg *arg = &args[i];
@@ -276,11 +277,16 @@ gen_prologue_slowpath(struct bpf_insn_pos *pos,
                                stack_offset), pos);
 
                ref = arg->ref;
+               probeid = BPF_FUNC_probe_read_kernel;
                while (ref) {
                        pr_debug("prologue: arg %d: offset %ld\n",
                                 i, ref->offset);
+
+                       if (ref->user_access)
+                               probeid = BPF_FUNC_probe_read_user;
+
                        err = gen_read_mem(pos, BPF_REG_3, BPF_REG_7,
-                                          ref->offset);
+                                          ref->offset, probeid);
                        if (err) {
                                pr_err("prologue: failed to generate probe_read function call\n");
                                goto errout;
index c4ca932..acef87d 100644 (file)
@@ -26,7 +26,7 @@ do { \
                YYABORT; \
 } while (0)
 
-static struct list_head* alloc_list()
+static struct list_head* alloc_list(void)
 {
        struct list_head *list;
 
@@ -349,7 +349,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
        struct list_head *list;
        char pmu_name[128];
 
-       snprintf(&pmu_name, 128, "%s-%s", $1, $3);
+       snprintf(pmu_name, sizeof(pmu_name), "%s-%s", $1, $3);
        free($1);
        free($3);
        if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0)
index 85e0c7f..f971d9a 100644 (file)
@@ -86,7 +86,6 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
                          struct perf_pmu_info *info);
 struct list_head *perf_pmu__alias(struct perf_pmu *pmu,
                                  struct list_head *head_terms);
-int perf_pmu_wrap(void);
 void perf_pmu_error(struct list_head *list, char *name, char const *msg);
 
 int perf_pmu__new_format(struct list_head *list, char *name,
index a08f373..df713a5 100644 (file)
@@ -1575,7 +1575,7 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
        }
 
        tmp = strchr(str, '@');
-       if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */
+       if (tmp && tmp != str && !strcmp(tmp + 1, "user")) { /* user attr */
                if (!user_access_is_supported()) {
                        semantic_error("ftrace does not support user access\n");
                        return -EINVAL;
@@ -1995,7 +1995,10 @@ static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
                if (depth < 0)
                        return depth;
        }
-       err = strbuf_addf(buf, "%+ld(", ref->offset);
+       if (ref->user_access)
+               err = strbuf_addf(buf, "%s%ld(", "+u", ref->offset);
+       else
+               err = strbuf_addf(buf, "%+ld(", ref->offset);
        return (err < 0) ? err : depth;
 }
 
index 8c85294..064b63a 100644 (file)
@@ -1044,7 +1044,7 @@ static struct {
        DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
        DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
        DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
-       DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*[u]<offset>*"),
+       DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*u]<offset>*"),
        DEFINE_TYPE(FTRACE_README_MULTIPROBE_EVENT, "*Create/append/*"),
        DEFINE_TYPE(FTRACE_README_IMMEDIATE_VALUE, "*\\imm-value,*"),
 };
index 3c6976f..57d0706 100644 (file)
@@ -668,7 +668,7 @@ static void print_aggr(struct perf_stat_config *config,
        int s;
        bool first;
 
-       if (!(config->aggr_map || config->aggr_get_id))
+       if (!config->aggr_map || !config->aggr_get_id)
                return;
 
        aggr_update_shadow(config, evlist);
@@ -1169,7 +1169,7 @@ static void print_percore(struct perf_stat_config *config,
        int s;
        bool first = true;
 
-       if (!(config->aggr_map || config->aggr_get_id))
+       if (!config->aggr_map || !config->aggr_get_id)
                return;
 
        if (config->percore_show_thread)
index db3c07b..b5f7a99 100644 (file)
@@ -51,7 +51,7 @@ struct nd_cmd_translate_spa {
                __u32 nfit_device_handle;
                __u32 _reserved;
                __u64 dpa;
-       } __packed devices[0];
+       } __packed devices[];
 
 } __packed;
 
@@ -74,7 +74,7 @@ struct nd_cmd_ars_err_inj_stat {
        struct nd_error_stat_query_record {
                __u64 err_inj_stat_spa_range_base;
                __u64 err_inj_stat_spa_range_length;
-       } __packed record[0];
+       } __packed record[];
 } __packed;
 
 #define ND_INTEL_SMART                  1
@@ -180,7 +180,7 @@ struct nd_intel_fw_send_data {
        __u32 context;
        __u32 offset;
        __u32 length;
-       __u8 data[0];
+       __u8 data[];
 /* this field is not declared due ot variable data from input */
 /*     __u32 status; */
 } __packed;
index a4605b5..8ec1922 100755 (executable)
@@ -263,10 +263,16 @@ CASENO=0
 
 testcase() { # testfile
   CASENO=$((CASENO+1))
-  desc=`grep "^#[ \t]*description:" $1 | cut -f2 -d:`
+  desc=`grep "^#[ \t]*description:" $1 | cut -f2- -d:`
   prlog -n "[$CASENO]$INSTANCE$desc"
 }
 
+checkreq() { # testfile
+  requires=`grep "^#[ \t]*requires:" $1 | cut -f2- -d:`
+  # Use eval to pass quoted-patterns correctly.
+  eval check_requires "$requires"
+}
+
 test_on_instance() { # testfile
   grep -q "^#[ \t]*flags:.*instance" $1
 }
@@ -356,7 +362,8 @@ trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
 
 __run_test() { # testfile
   # setup PID and PPID, $$ is not updated.
-  (cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x; initialize_ftrace; . $1)
+  (cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x;
+   checkreq $1; initialize_ftrace; . $1)
   [ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
 }
 
index 3b1f45e..13b4dab 100644 (file)
@@ -1,9 +1,8 @@
 #!/bin/sh
 # description: Snapshot and tracing setting
+# requires: snapshot
 # flags: instance
 
-[ ! -f snapshot ] && exit_unsupported
-
 echo "Set tracing off"
 echo 0 > tracing_on
 
index 5058fbc..435d07b 100644 (file)
@@ -1,10 +1,9 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: trace_pipe and trace_marker
+# requires: trace_marker
 # flags: instance
 
-[ ! -f trace_marker ] && exit_unsupported
-
 echo "test input 1" > trace_marker
 
 : "trace interface never consume the ring buffer"
index 801ecb6..e52e470 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Test ftrace direct functions against kprobes
+# requires: kprobe_events
 
 rmmod ftrace-direct ||:
 if ! modprobe ftrace-direct ; then
@@ -8,11 +9,6 @@ if ! modprobe ftrace-direct ; then
   exit_unresolved;
 fi
 
-if [ ! -f kprobe_events ]; then
-       echo "No kprobe_events file -please build CONFIG_KPROBE_EVENTS"
-       exit_unresolved;
-fi
-
 echo "Let the module run a little"
 sleep 1
 
index c6d8387..68550f9 100644 (file)
@@ -1,11 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - add/remove kprobe events
-
-[ -f dynamic_events ] || exit_unsupported
-
-grep -q "place: \[<module>:\]<symbol>" README || exit_unsupported
-grep -q "place (kretprobe): \[<module>:\]<symbol>" README || exit_unsupported
+# requires: dynamic_events "place: [<module>:]<symbol>":README "place (kretprobe): [<module>:]<symbol>":README
 
 echo 0 > events/enable
 echo > dynamic_events
index 62b77b5..2b94611 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - add/remove synthetic events
-
-[ -f dynamic_events ] || exit_unsupported
-
-grep -q "s:\[synthetic/\]" README || exit_unsupported
+# requires: dynamic_events "s:[synthetic/]":README
 
 echo 0 > events/enable
 echo > dynamic_events
index e084210..c969be9 100644 (file)
@@ -1,16 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - selective clear (compatibility)
-
-[ -f dynamic_events ] || exit_unsupported
-
-grep -q "place: \[<module>:\]<symbol>" README || exit_unsupported
-grep -q "place (kretprobe): \[<module>:\]<symbol>" README || exit_unsupported
-
-grep -q "s:\[synthetic/\]" README || exit_unsupported
-
-[ -f synthetic_events ] || exit_unsupported
-[ -f kprobe_events ] || exit_unsupported
+# requires: dynamic_events kprobe_events synthetic_events "place: [<module>:]<symbol>":README "place (kretprobe): [<module>:]<symbol>":README "s:[synthetic/]":README
 
 echo 0 > events/enable
 echo > dynamic_events
index 901922e..16d543e 100644 (file)
@@ -1,13 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Generic dynamic event - generic clear event
-
-[ -f dynamic_events ] || exit_unsupported
-
-grep -q "place: \[<module>:\]<symbol>" README || exit_unsupported
-grep -q "place (kretprobe): \[<module>:\]<symbol>" README || exit_unsupported
-
-grep -q "s:\[synthetic/\]" README || exit_unsupported
+# requires: dynamic_events "place: [<module>:]<symbol>":README "place (kretprobe): [<module>:]<symbol>":README "s:[synthetic/]":README
 
 echo 0 > events/enable
 echo > dynamic_events
index dfb0d51..cfe5bd2 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event tracing - enable/disable with event level files
+# requires: set_event events/sched
 # flags: instance
 
 do_reset() {
@@ -13,11 +14,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
 echo 'sched:sched_switch' > set_event
 
 yield
index f0f366f..e6eb78f 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event tracing - restricts events based on pid notrace filtering
+# requires: set_event events/sched set_event_pid set_event_notrace_pid
 # flags: instance
 
 do_reset() {
@@ -56,16 +57,6 @@ enable_events() {
     echo 1 > tracing_on
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f set_event_pid -o ! -f set_event_notrace_pid ]; then
-    echo "event pid notrace filtering is not supported"
-    exit_unsupported
-fi
-
 echo 0 > options/event-fork
 
 do_reset
index f9cb214..7f5f97d 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event tracing - restricts events based on pid
+# requires: set_event set_event_pid events/sched
 # flags: instance
 
 do_reset() {
@@ -16,16 +17,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f set_event_pid ]; then
-    echo "event pid filtering is not supported"
-    exit_unsupported
-fi
-
 echo 0 > options/event-fork
 
 echo 1 > events/sched/sched_switch/enable
index 83a8c57..b1ede62 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event tracing - enable/disable with subsystem level files
+# requires: set_event events/sched/enable
 # flags: instance
 
 do_reset() {
@@ -13,11 +14,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
 echo 'sched:*' > set_event
 
 yield
index 84d7bda..93c10ea 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event tracing - enable/disable with top level files
+# requires: available_events set_event events/enable
 
 do_reset() {
     echo > set_event
@@ -12,11 +13,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
 echo '*:*' > set_event
 
 yield
index f598538..cf3ea42 100644 (file)
@@ -1,17 +1,11 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function graph filters with stack tracer
+# requires: stack_trace set_ftrace_filter function_graph:tracer
 
 # Make sure that function graph filtering works, and is not
 # affected by other tracers enabled (like stack tracer)
 
-if ! grep -q function_graph available_tracers; then
-    echo "no function graph tracer configured"
-    exit_unsupported
-fi
-
-check_filter_file set_ftrace_filter
-
 do_reset() {
     if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then
            echo 0 > /proc/sys/kernel/stack_tracer_enabled
@@ -37,12 +31,6 @@ fi
 
 echo function_graph > current_tracer
 
-if [ ! -f stack_trace ]; then
-    echo "Stack tracer not configured"
-    do_reset
-    exit_unsupported;
-fi
-
 echo "Now testing with stack tracer"
 
 echo 1 > /proc/sys/kernel/stack_tracer_enabled
index d610f47..b3ccdae 100644 (file)
@@ -1,16 +1,10 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function graph filters
+# requires: set_ftrace_filter function_graph:tracer
 
 # Make sure that function graph filtering works
 
-if ! grep -q function_graph available_tracers; then
-    echo "no function graph tracer configured"
-    exit_unsupported
-fi
-
-check_filter_file set_ftrace_filter
-
 fail() { # msg
     echo $1
     exit_fail
index 28936f4..4b994b6 100644 (file)
@@ -1,16 +1,10 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function glob filters
+# requires: set_ftrace_filter function:tracer
 
 # Make sure that function glob matching filter works.
 
-if ! grep -q function available_tracers; then
-    echo "no function tracer configured"
-    exit_unsupported
-fi
-
-check_filter_file set_ftrace_filter
-
 disable_tracing
 clear_trace
 
index 71db68a..acb17ce 100644 (file)
@@ -1,22 +1,11 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function pid notrace filters
+# requires: set_ftrace_notrace_pid set_ftrace_filter function:tracer
 # flags: instance
 
 # Make sure that function pid matching filter with notrace works.
 
-if ! grep -q function available_tracers; then
-    echo "no function tracer configured"
-    exit_unsupported
-fi
-
-if [ ! -f set_ftrace_notrace_pid ]; then
-    echo "set_ftrace_notrace_pid not found? Is function tracer not set?"
-    exit_unsupported
-fi
-
-check_filter_file set_ftrace_filter
-
 do_function_fork=1
 
 if [ ! -f options/function-fork ]; then
index d58403c..9f0a968 100644 (file)
@@ -1,23 +1,12 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function pid filters
+# requires: set_ftrace_pid set_ftrace_filter function:tracer
 # flags: instance
 
 # Make sure that function pid matching filter works.
 # Also test it on an instance directory
 
-if ! grep -q function available_tracers; then
-    echo "no function tracer configured"
-    exit_unsupported
-fi
-
-if [ ! -f set_ftrace_pid ]; then
-    echo "set_ftrace_pid not found? Is function tracer not set?"
-    exit_unsupported
-fi
-
-check_filter_file set_ftrace_filter
-
 do_function_fork=1
 
 if [ ! -f options/function-fork ]; then
index b2aff78..0f41e44 100644 (file)
@@ -1,10 +1,9 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - stacktrace filter command
+# requires: set_ftrace_filter
 # flags: instance
 
-check_filter_file set_ftrace_filter
-
 echo _do_fork:stacktrace >> set_ftrace_filter
 
 grep -q "_do_fork:stacktrace:unlimited" set_ftrace_filter
index 71fa3f4..0c6cf77 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function trace with cpumask
+# requires: function:tracer
 
 if ! which nproc ; then
   nproc() {
@@ -15,11 +16,6 @@ if [ $NP -eq 1 ] ;then
   exit_unresolved
 fi
 
-if ! grep -q "function" available_tracers ; then
-  echo "Function trace is not enabled"
-  exit_unsupported
-fi
-
 ORIG_CPUMASK=`cat tracing_cpumask`
 
 do_reset() {
index e9b1fd5..3145b0f 100644 (file)
@@ -3,15 +3,14 @@
 # description: ftrace - test for function event triggers
 # flags: instance
 #
+# The triggers are set within the set_ftrace_filter file
+# requires: set_ftrace_filter
+#
 # Ftrace allows to add triggers to functions, such as enabling or disabling
 # tracing, enabling or disabling trace events, or recording a stack trace
 # within the ring buffer.
 #
 # This test is designed to test event triggers
-#
-
-# The triggers are set within the set_ftrace_filter file
-check_filter_file set_ftrace_filter
 
 do_reset() {
     reset_ftrace_filter
index 1a4b4a4..37c8feb 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function trace on module
-
-check_filter_file set_ftrace_filter
+# requires: set_ftrace_filter
 
 : "mod: allows to filter a non exist function"
 echo 'non_exist_func:mod:non_exist_module' > set_ftrace_filter
index 0d50105..4daeffb 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function profiling
-
-[ ! -f function_profile_enabled ] && exit_unsupported
+# requires: function_profile_enabled
 
 : "Enable function profile"
 echo 1 > function_profile_enabled
index a3dadb6..1dbd766 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - function profiler with function tracing
+# requires: function_profile_enabled set_ftrace_filter function_graph:tracer
 
 # There was a bug after a rewrite of the ftrace infrastructure that
 # caused the function_profiler not to be able to run with the function
 # This test triggers those bugs on those kernels.
 #
 # We need function_graph and profiling to to run this test
-if ! grep -q function_graph available_tracers; then
-    echo "no function graph tracer configured"
-    exit_unsupported;
-fi
-
-check_filter_file set_ftrace_filter
-
-if [ ! -f function_profile_enabled ]; then
-    echo "function_profile_enabled not found, function profiling enabled?"
-    exit_unsupported
-fi
 
 fail() { # mesg
     echo $1
index 70bad44..e96e279 100644 (file)
@@ -2,6 +2,9 @@
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - test reading of set_ftrace_filter
 #
+# The triggers are set within the set_ftrace_filter file
+# requires: set_ftrace_filter
+#
 # The set_ftrace_filter file of ftrace is used to list functions as well as
 # triggers (probes) attached to functions. The code to read this file is not
 # straight forward and has had various bugs in the past. This test is designed
@@ -9,9 +12,6 @@
 # file in various ways (cat vs dd).
 #
 
-# The triggers are set within the set_ftrace_filter file
-check_filter_file set_ftrace_filter
-
 fail() { # mesg
     echo $1
     exit_fail
index 51e9e80..61264e4 100644 (file)
@@ -1,15 +1,9 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - Max stack tracer
+# requires: stack_trace stack_trace_filter
 # Test the basic function of max-stack usage tracing
 
-if [ ! -f stack_trace ]; then
-  echo "Max stack tracer is not supported - please make CONFIG_STACK_TRACER=y"
-  exit_unsupported
-fi
-
-check_filter_file stack_trace_filter
-
 echo > stack_trace_filter
 echo 0 > stack_max_size
 echo 1 > /proc/sys/kernel/stack_tracer_enabled
index 3ed173f..aee2228 100644 (file)
@@ -3,6 +3,9 @@
 # description: ftrace - test for function traceon/off triggers
 # flags: instance
 #
+# The triggers are set within the set_ftrace_filter file
+# requires: set_ftrace_filter
+#
 # Ftrace allows to add triggers to functions, such as enabling or disabling
 # tracing, enabling or disabling trace events, or recording a stack trace
 # within the ring buffer.
@@ -10,9 +13,6 @@
 # This test is designed to test enabling and disabling tracing triggers
 #
 
-# The triggers are set within the set_ftrace_filter file
-check_filter_file set_ftrace_filter
-
 fail() { # mesg
     echo $1
     exit_fail
index 2346582..6c19062 100644 (file)
@@ -1,21 +1,15 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: ftrace - test tracing error log support
+# event tracing is currently the only ftrace tracer that uses the
+# tracing error_log, hence this check
+# requires: set_event error_log
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-# event tracing is currently the only ftrace tracer that uses the
-# tracing error_log, hence this check
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-[ -f error_log ] || exit_unsupported
-
 ftrace_errlog_check 'event filter parse error' '((sig >= 10 && sig < 15) || dsig ^== 17) && comm != bash' 'events/signal/signal_generate/filter'
 
 exit 0
index 697c77e..c5dec55 100644 (file)
@@ -1,10 +1,3 @@
-check_filter_file() { # check filter file introduced by dynamic ftrace
-    if [ ! -f "$1" ]; then
-        echo "$1 not found? Is dynamic ftrace not set?"
-        exit_unsupported
-    fi
-}
-
 clear_trace() { # reset trace output
     echo > trace
 }
@@ -113,6 +106,27 @@ initialize_ftrace() { # Reset ftrace to initial-state
     enable_tracing
 }
 
+check_requires() { # Check required files and tracers
+    for i in "$@" ; do
+        r=${i%:README}
+        t=${i%:tracer}
+        if [ $t != $i ]; then
+            if ! grep -wq $t available_tracers ; then
+                echo "Required tracer $t is not configured."
+                exit_unsupported
+            fi
+        elif [ $r != $i ]; then
+            if ! grep -Fq "$r" README ; then
+                echo "Required feature pattern \"$r\" is not in README."
+                exit_unsupported
+            fi
+        elif [ ! -e $i ]; then
+            echo "Required feature interface $i doesn't exist."
+            exit_unsupported
+        fi
+    done
+}
+
 LOCALHOST=127.0.0.1
 
 yield() {
index 4fa0f79..0eb47fb 100644 (file)
@@ -1,11 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Test creation and deletion of trace instances while setting an event
-
-if [ ! -d instances ] ; then
-    echo "no instance directory with this kernel"
-    exit_unsupported;
-fi
+# requires: instances
 
 fail() { # mesg
     rmdir foo 2>/dev/null
index b846512..607521d 100644 (file)
@@ -1,11 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Test creation and deletion of trace instances
-
-if [ ! -d instances ] ; then
-    echo "no instance directory with this kernel"
-    exit_unsupported;
-fi
+# requires: instances
 
 fail() { # mesg
     rmdir x y z 2>/dev/null
index bb1eb5a..eba858c 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event - adding and removing
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 echo p:myevent _do_fork > kprobe_events
 grep myevent kprobe_events
index 442c1a8..d10bf4f 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event - busy event check
-
-[ -f kprobe_events ] || exit_unsupported
+# requires: kprobe_events
 
 echo p:myevent _do_fork > kprobe_events
 test -d events/kprobes/myevent
index bcdecf8..61f2ac4 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event with arguments
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 echo 'p:testprobe _do_fork $stack $stack0 +0($stack)' > kprobe_events
 grep testprobe kprobe_events | grep -q 'arg1=\$stack arg2=\$stack0 arg3=+0(\$stack)'
index 15c1f70..05aaeed 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event with comm arguments
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 grep -A1 "fetcharg:" README | grep -q "\$comm" || exit_unsupported # this is too old
 
index 46e7744..b5fa054 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event string type argument
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 case `uname -m` in
 x86_64)
index 2b6dd33..b8c75a3 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event symbol argument
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 SYMBOL="linux_proc_banner"
 
index 6f0f199..474ca1a 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event argument syntax
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-
-grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+# requires: kprobe_events "x8/16/32/64":README
 
 PROBEFUNC="vfs_read"
 GOODREG=
index 81490ec..0610e0b 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobes event arguments with types
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-
-grep "x8/16/32/64" README > /dev/null || exit_unsupported # version issue
+# requires: kprobe_events "x8/16/32/64":README
 
 gen_event() { # Bitsize
   echo "p:testprobe _do_fork \$stack0:s$1 \$stack0:u$1 \$stack0:x$1 \$stack0:b4@4/$1"
index 0f60087..a30a9c0 100644 (file)
@@ -1,10 +1,8 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event user-memory access
+# requires: kprobe_events '$arg<N>':README
 
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-
-grep -q '\$arg<N>' README || exit_unresolved # depends on arch
 grep -A10 "fetcharg:" README | grep -q 'ustring' || exit_unsupported
 grep -A10 "fetcharg:" README | grep -q '\[u\]<offset>' || exit_unsupported
 
index 3ff2367..1f6981e 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event auto/manual naming
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 :;: "Add an event on function without name" ;:
 
index df50728..81d8b58 100644 (file)
@@ -1,11 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event with function tracer
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-grep "function" available_tracers || exit_unsupported # this is configurable
-
-check_filter_file set_ftrace_filter
+# requires: kprobe_events stack_trace_filter function:tracer
 
 # prepare
 echo nop > current_tracer
index d861bd7..7e74ee1 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event - probing module
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 rmmod trace-printk ||:
 if ! modprobe trace-printk ; then
index 44494ba..366b7e1 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Create/delete multiprobe on kprobe event
-
-[ -f kprobe_events ] || exit_unsupported
-
-grep -q "Create/append/" README || exit_unsupported
+# requires: kprobe_events "Create/append/":README
 
 # Choose 2 symbols for target
 SYM1=_do_fork
index eb0f4ab..b4d8346 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe event parser error log check
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-
-[ -f error_log ] || exit_unsupported
+# requires: kprobe_events error_log
 
 check_error() { # command-with-error-pos-by-^
     ftrace_errlog_check 'trace_kprobe' "$1" 'kprobe_events'
index ac9ab4a..523fde6 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kretprobe dynamic event with arguments
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 # Add new kretprobe event
 echo 'r:testprobe2 _do_fork $retval' > kprobe_events
index 8e05b17..4f0b268 100644 (file)
@@ -1,9 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kretprobe dynamic event with maxactive
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
-grep -q 'r\[maxactive\]' README || exit_unsupported # this is older version
+# requires: kprobe_events 'r[maxactive]':README
 
 # Test if we successfully reject unknown messages
 if echo 'a:myprobeaccept inet_csk_accept' > kprobe_events; then false; else true; fi
index 6e3dbe5..312d237 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Register/unregister many kprobe events
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 # ftrace fentry skip size depends on the machine architecture.
 # Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le
index a902aa0..624269c 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe events - probe points
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 TARGET_FUNC=tracefs_create_dir
 
index 0384b52..ff6c44a 100644 (file)
@@ -1,8 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Kprobe dynamic event - adding and removing
-
-[ -f kprobe_events ] || exit_unsupported # this is configurable
+# requires: kprobe_events
 
 ! grep -q 'myevent' kprobe_profile
 echo p:myevent _do_fork > kprobe_events
index 14229d5..7b5b60c 100644 (file)
@@ -1,10 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Uprobe event parser error log check
-
-[ -f uprobe_events ] || exit_unsupported # this is configurable
-
-[ -f error_log ] || exit_unsupported
+# requires: uprobe_events error_log
 
 check_error() { # command-with-error-pos-by-^
     ftrace_errlog_check 'trace_uprobe' "$1" 'uprobe_events'
index 2b82c80..22bff12 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: test for the preemptirqsoff tracer
+# requires: preemptoff:tracer irqsoff:tracer
 
 MOD=preemptirq_delay_test
 
@@ -27,9 +28,6 @@ unres() { #msg
 modprobe $MOD || unres "$MOD module not available"
 rmmod $MOD
 
-grep -q "preemptoff" available_tracers || unsup "preemptoff tracer not enabled"
-grep -q "irqsoff" available_tracers || unsup "irqsoff tracer not enabled"
-
 reset_tracer
 
 # Simulate preemptoff section for half a second couple of times
index e1a5d14..2cd8947 100644 (file)
@@ -1,6 +1,10 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: %HERE DESCRIBE WHAT THIS DOES%
+# requires: %HERE LIST THE REQUIRED FILES, TRACERS OR README-STRINGS%
+# The required tracer needs :tracer suffix, e.g. function:tracer
+# The required README string needs :README suffix, e.g. "x8/16/32/64":README
+# and the README string is treated as a fixed-string instead of regexp pattern.
 # you have to add ".tc" extention for your testcase file
 # Note that all tests are run with "errexit" option.
 
index b0893d7..11be10e 100644 (file)
@@ -1,17 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Test wakeup tracer
+# requires: wakeup:tracer
 
 if ! which chrt ; then
   echo "chrt is not found. This test requires nice command."
   exit_unresolved
 fi
 
-if ! grep -wq "wakeup" available_tracers ; then
-  echo "wakeup tracer is not supported"
-  exit_unsupported
-fi
-
 echo wakeup > current_tracer
 echo 1 > tracing_on
 echo 0 > tracing_max_latency
index b9b6669..3a77198 100644 (file)
@@ -1,17 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: Test wakeup RT tracer
+# requires: wakeup_rt:tracer
 
 if ! which chrt ; then
   echo "chrt is not found. This test requires chrt command."
   exit_unresolved
 fi
 
-if ! grep -wq "wakeup_rt" available_tracers ; then
-  echo "wakeup_rt tracer is not supported"
-  exit_unsupported
-fi
-
 echo wakeup_rt > current_tracer
 echo 1 > tracing_on
 echo 0 > tracing_max_latency
index 3f2aee1..1590d6b 100644 (file)
@@ -1,24 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger expected fail actions
+# requires: set_event snapshot "snapshot()":README
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f snapshot ]; then
-    echo "snapshot is not supported"
-    exit_unsupported
-fi
-
-grep -q "snapshot()" README || exit_unsupported # version issue
-
 echo "Test expected snapshot action failure"
 
 echo 'hist:keys=comm:onmatch(sched.sched_wakeup).snapshot()' >> events/sched/sched_waking/trigger && exit_fail
index e232059..41119e0 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test field variable support
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test field variable support"
 
 echo 'wakeup_latency u64 lat; pid_t pid; int prio; char comm[16]' > synthetic_events
index 07cfcb8..7449a4b 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event combined histogram trigger
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test create synthetic event"
 
 echo 'waking_latency  u64 lat pid_t pid' > synthetic_events
index 73e413c..3ad6e3f 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test multiple actions on hist trigger
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test multiple actions on hist trigger"
 echo 'wakeup_latency u64 lat; pid_t pid' >> synthetic_events
 TRIGGER1=events/sched/sched_wakeup/trigger
index c80007a..adaabb8 100644 (file)
@@ -1,19 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger onchange action
+# requires: set_event "onchange(var)":README
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-grep -q "onchange(var)" README || exit_unsupported # version issue
-
 echo "Test onchange action"
 
 echo 'hist:keys=comm:newprio=prio:onchange($newprio).save(comm,prio) if comm=="ping"' >> events/sched/sched_waking/trigger
index ebe0ad8..20e3947 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger onmatch action
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test create synthetic event"
 
 echo 'wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
index 2a2ef76..f4b03ab 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger onmatch-onmax action
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test create synthetic event"
 
 echo 'wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
index 98d73bf..71c9b59 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger onmax action
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test create synthetic event"
 
 echo 'wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
index 01b01b9..67fa328 100644 (file)
@@ -1,31 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger snapshot action
+# requires: set_event snapshot events/sched/sched_process_fork/hist "onchange(var)":README "snapshot()":README
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f snapshot ]; then
-    echo "snapshot is not supported"
-    exit_unsupported
-fi
-
-grep -q "onchange(var)" README || exit_unsupported # version issue
-
-grep -q "snapshot()" README || exit_unsupported # version issue
-
 echo "Test snapshot action"
 
 echo 1 > events/sched/enable
index df44b14..a152b55 100644 (file)
@@ -1,22 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test synthetic event create remove
+# requires: set_event synthetic_events
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
 echo "Test create synthetic event"
 
 echo 'wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
index 88e6c3f..59216f3 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test synthetic_events syntax parser
+# requires: set_event synthetic_events
 
 do_reset() {
     reset_trigger
@@ -14,16 +15,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
 reset_tracer
 do_reset
 
index c3baa48..c126d23 100644 (file)
@@ -1,29 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test inter-event histogram trigger trace action
+# requires: set_event synthetic_events events/sched/sched_process_fork/hist "trace(<synthetic_event>":README
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic event is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
-grep -q "trace(<synthetic_event>" README || exit_unsupported # version issue
-
 echo "Test create synthetic event"
 
 echo 'wakeup_latency  u64 lat pid_t pid char comm[16]' > synthetic_events
index eddb51e..c226ace 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test event enable/disable trigger
+# requires: set_event events/sched/sched_process_fork/trigger
 # flags: instance
 
 fail() { #msg
@@ -8,16 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
 FEATURE=`grep enable_event events/sched/sched_process_fork/trigger`
 if [ -z "$FEATURE" ]; then
     echo "event enable/disable trigger is not supported"
index 2dcc229..d9a198c 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test trigger filter
+# requires: set_event events/sched/sched_process_fork/trigger
 # flags: instance
 
 fail() { #msg
@@ -8,16 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test trigger filter"
 echo 1 > tracing_on
 echo 'traceoff if child_pid == 0' > events/sched/sched_process_fork/trigger
index fab4431..4562e13 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test histogram modifiers
+# requires: set_event events/sched/sched_process_fork/trigger events/sched/sched_process_fork/hist
 # flags: instance
 
 fail() { #msg
@@ -8,21 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test histogram with execname modifier"
 
 echo 'hist:keys=common_pid.execname' > events/sched/sched_process_fork/trigger
index d44087a..52cfe78 100644 (file)
@@ -1,23 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test histogram parser errors
-
-if [ ! -f set_event -o ! -d events/kmem ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/kmem/kmalloc/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/kmem/kmalloc/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
-[ -f error_log ] || exit_unsupported
+# requires: set_event events/kmem/kmalloc/trigger events/kmem/kmalloc/hist error_log
 
 check_error() { # command-with-error-pos-by-^
     ftrace_errlog_check 'hist:kmem:kmalloc' "$1" 'events/kmem/kmalloc/trigger'
index 177e8d4..2950bfb 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test histogram trigger
+# requires: set_event events/sched/sched_process_fork/trigger events/sched/sched_process_fork/hist
 # flags: instance
 
 fail() { #msg
@@ -8,22 +9,7 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
-echo "Test histogram basic tigger"
+echo "Test histogram basic trigger"
 
 echo 'hist:keys=parent_pid:vals=child_pid' > events/sched/sched_process_fork/trigger
 for i in `seq 1 10` ; do ( echo "forked" > /dev/null); done
index 68ff3f4..7129b52 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test multiple histogram triggers
+# requires: set_event events/sched/sched_process_fork/trigger events/sched/sched_process_fork/hist
 # flags: instance
 
 fail() { #msg
@@ -8,21 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test histogram multiple triggers"
 
 echo 'hist:keys=parent_pid:vals=child_pid' > events/sched/sched_process_fork/trigger
index ac73850..33f5bde 100644 (file)
@@ -1,27 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test snapshot-trigger
+# requires: set_event events/sched/sched_process_fork/trigger snapshot
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f snapshot ]; then
-    echo "snapshot is not supported"
-    exit_unsupported
-fi
-
 FEATURE=`grep snapshot events/sched/sched_process_fork/trigger`
 if [ -z "$FEATURE" ]; then
     echo "snapshot trigger is not supported"
index 398c05c..320ea9b 100644 (file)
@@ -1,29 +1,20 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test stacktrace-trigger
+# requires: set_event events/sched/sched_process_fork/trigger
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
 FEATURE=`grep stacktrace events/sched/sched_process_fork/trigger`
 if [ -z "$FEATURE" ]; then
     echo "stacktrace trigger is not supported"
     exit_unsupported
 fi
 
-echo "Test stacktrace tigger"
+echo "Test stacktrace trigger"
 echo 0 > trace
 echo 0 > options/stacktrace
 echo 'stacktrace' > events/sched/sched_process_fork/trigger
index ab6bedb..68f3af9 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: trace_marker trigger - test histogram trigger
+# requires: set_event events/ftrace/print/trigger events/ftrace/print/hist
 # flags: instance
 
 fail() { #msg
@@ -8,27 +9,7 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -d events/ftrace/print ]; then
-    echo "event trace_marker is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
-echo "Test histogram trace_marker tigger"
+echo "Test histogram trace_marker trigger"
 
 echo 'hist:keys=common_pid' > events/ftrace/print/trigger
 for i in `seq 1 10` ; do echo "hello" > trace_marker; done
index df246e5..27da2db 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: trace_marker trigger - test snapshot trigger
+# requires: set_event snapshot events/ftrace/print/trigger
 # flags: instance
 
 fail() { #msg
@@ -8,26 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f snapshot ]; then
-    echo "snapshot is not supported"
-    exit_unsupported
-fi
-
-if [ ! -d events/ftrace/print ]; then
-    echo "event trace_marker is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
 test_trace() {
     file=$1
     x=$2
@@ -46,7 +27,7 @@ test_trace() {
     done
 }
 
-echo "Test snapshot trace_marker tigger"
+echo "Test snapshot trace_marker trigger"
 
 echo 'snapshot' > events/ftrace/print/trigger
 
index 18b4d1c..531139f 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: trace_marker trigger - test histogram with synthetic event against kernel event
+# requires: set_event synthetic_events events/sched/sched_waking events/ftrace/print/trigger events/ftrace/print/hist
 # flags:
 
 fail() { #msg
@@ -8,36 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic events not supported"
-    exit_unsupported
-fi
-
-if [ ! -d events/ftrace/print ]; then
-    echo "event trace_marker is not supported"
-    exit_unsupported
-fi
-
-if [ ! -d events/sched/sched_waking ]; then
-    echo "event sched_waking is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test histogram kernel event to trace_marker latency histogram trigger"
 
 echo 'latency u64 lat' > synthetic_events
index dd262d6..cc99cbb 100644 (file)
@@ -1,6 +1,7 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: trace_marker trigger - test histogram with synthetic event
+# requires: set_event synthetic_events events/ftrace/print/trigger events/ftrace/print/hist
 # flags:
 
 fail() { #msg
@@ -8,31 +9,6 @@ fail() { #msg
     exit_fail
 }
 
-if [ ! -f set_event ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f synthetic_events ]; then
-    echo "synthetic events not supported"
-    exit_unsupported
-fi
-
-if [ ! -d events/ftrace/print ]; then
-    echo "event trace_marker is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/ftrace/print/hist ]; then
-    echo "hist trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test histogram trace_marker to trace_marker latency histogram trigger"
 
 echo 'latency u64 lat' > synthetic_events
index d5d2dcb..9ca0467 100644 (file)
@@ -1,22 +1,13 @@
 #!/bin/sh
 # SPDX-License-Identifier: GPL-2.0
 # description: event trigger - test traceon/off trigger
+# requires: set_event events/sched/sched_process_fork/trigger
 
 fail() { #msg
     echo $1
     exit_fail
 }
 
-if [ ! -f set_event -o ! -d events/sched ]; then
-    echo "event tracing is not supported"
-    exit_unsupported
-fi
-
-if [ ! -f events/sched/sched_process_fork/trigger ]; then
-    echo "event trigger is not supported"
-    exit_unsupported
-fi
-
 echo "Test traceoff trigger"
 echo 1 > tracing_on
 echo 'traceoff' > events/sched/sched_process_fork/trigger
index c0aa46c..252140a 100644 (file)
@@ -1615,6 +1615,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
 # define ARCH_REGS     s390_regs
 # define SYSCALL_NUM   gprs[2]
 # define SYSCALL_RET   gprs[2]
+# define SYSCALL_NUM_RET_SHARE_REG
 #elif defined(__mips__)
 # define ARCH_REGS     struct pt_regs
 # define SYSCALL_NUM   regs[2]