Merge tag 'v4.17-rc2' into docs-next
authorJonathan Corbet <corbet@lwn.net>
Fri, 27 Apr 2018 23:13:20 +0000 (17:13 -0600)
committerJonathan Corbet <corbet@lwn.net>
Fri, 27 Apr 2018 23:13:20 +0000 (17:13 -0600)
  Merge -rc2 to pick up the changes to
  Documentation/core-api/kernel-api.rst that hit mainline via the
  networking tree.  In their absence, subsequent patches cannot be
  applied.

326 files changed:
Documentation/core-api/kernel-api.rst
Documentation/devicetree/bindings/thermal/exynos-thermal.txt
Documentation/devicetree/bindings/thermal/thermal.txt
Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt [new file with mode: 0644]
Documentation/devicetree/bindings/timer/nxp,tpm-timer.txt
Documentation/livepatch/shadow-vars.txt
Documentation/networking/filter.txt
Documentation/networking/ip-sysctl.txt
MAINTAINERS
Makefile
arch/arm64/kernel/traps.c
arch/arm64/mm/kasan_init.c
arch/mips/boot/dts/img/boston.dts
arch/mips/include/asm/io.h
arch/mips/include/asm/uaccess.h
arch/mips/lib/memset.S
arch/parisc/kernel/Makefile
arch/powerpc/kernel/eeh_pe.c
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/setup_64.c
arch/powerpc/lib/feature-fixups.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/sysdev/xive/native.c
arch/s390/Kbuild
arch/s390/Kconfig
arch/s390/boot/Makefile
arch/s390/boot/compressed/.gitignore
arch/s390/configs/debug_defconfig [new file with mode: 0644]
arch/s390/configs/default_defconfig [deleted file]
arch/s390/configs/gcov_defconfig [deleted file]
arch/s390/configs/performance_defconfig
arch/s390/defconfig
arch/s390/hypfs/inode.c
arch/s390/include/asm/kexec.h
arch/s390/include/asm/purgatory.h [new file with mode: 0644]
arch/s390/include/asm/setup.h
arch/s390/include/uapi/asm/signal.h
arch/s390/kernel/Makefile
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_wrapper.c
arch/s390/kernel/kexec_elf.c [new file with mode: 0644]
arch/s390/kernel/kexec_image.c [new file with mode: 0644]
arch/s390/kernel/machine_kexec_file.c [new file with mode: 0644]
arch/s390/kernel/nospec-branch.c
arch/s390/kernel/perf_cpum_cf_events.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscalls/syscall.tbl
arch/s390/purgatory/.gitignore [new file with mode: 0644]
arch/s390/purgatory/Makefile [new file with mode: 0644]
arch/s390/purgatory/head.S [new file with mode: 0644]
arch/s390/purgatory/purgatory.c [new file with mode: 0644]
arch/x86/events/intel/uncore_snbep.c
arch/x86/include/asm/asm.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/processor.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/kexec-bzimage64.c
arch/x86/kernel/ldt.c
arch/x86/kernel/pci-nommu.c [deleted file]
arch/x86/kernel/smpboot.c
arch/x86/kernel/tsc.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/dump_pagetables.c
arch/x86/power/hibernate_64.c
drivers/atm/iphase.c
drivers/block/rbd.c
drivers/char/random.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/timer-imx-tpm.c
drivers/clocksource/timer-npcm7xx.c [new file with mode: 0644]
drivers/dax/device.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h
drivers/gpu/drm/drm_dp_dual_mode_helper.c
drivers/gpu/drm/exynos/exynos_drm_fb.c
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/display.c
drivers/gpu/drm/i915/gvt/dmabuf.c
drivers/gpu/drm/i915/gvt/fb_decoder.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/gtt.h
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_lrc.c
drivers/gpu/drm/vc4/vc4_bo.c
drivers/gpu/drm/vc4/vc4_validate_shaders.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hidraw.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/wacom_wac.c
drivers/isdn/mISDN/dsp_hwec.c
drivers/isdn/mISDN/l1oip_core.c
drivers/md/md.c
drivers/md/raid1.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
drivers/mmc/host/sdhci-pci-core.c
drivers/net/dsa/mv88e6xxx/hwtstamp.c
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
drivers/net/ethernet/broadcom/bnxt/bnxt_nvm_defs.h
drivers/net/ethernet/hisilicon/hns/hnae.h
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/ibm/ibmvnic.h
drivers/net/ethernet/marvell/mvpp2.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.h
drivers/net/ethernet/netronome/nfp/flower/main.c
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c
drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
drivers/net/ethernet/sfc/ef10.c
drivers/net/ethernet/sfc/farch.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/macsec.c
drivers/net/phy/microchip.c
drivers/net/team/team.c
drivers/net/tun.c
drivers/net/usb/qmi_wwan.c
drivers/net/virtio_net.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/nvdimm/Kconfig
drivers/nvdimm/dimm_devs.c
drivers/nvdimm/of_pmem.c
drivers/rapidio/devices/rio_mport_cdev.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/sclp_early_core.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/smsgiucv.c
drivers/watchdog/aspeed_wdt.c
drivers/watchdog/renesas_wdt.c
drivers/watchdog/sch311x_wdt.c
drivers/watchdog/w83977f_wdt.c
drivers/watchdog/wafer5823wdt.c
drivers/xen/xen-pciback/conf_space_quirks.c
drivers/xen/xen-pciback/pci_stub.c
drivers/xen/xenbus/xenbus_dev_frontend.c
fs/afs/server.c
fs/autofs4/root.c
fs/binfmt_elf.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/print-tree.c
fs/btrfs/print-tree.h
fs/btrfs/qgroup.c
fs/btrfs/transaction.c
fs/btrfs/transaction.h
fs/ceph/inode.c
fs/cifs/cifs_debug.h
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/smb2ops.c
fs/cifs/smbdirect.c
fs/ecryptfs/crypto.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ext2/file.c
fs/fs-writeback.c
fs/isofs/compress.c
fs/isofs/inode.c
fs/jffs2/super.c
fs/namespace.c
fs/notify/fanotify/fanotify.c
fs/notify/fsnotify.c
fs/orangefs/super.c
fs/proc/base.c
fs/proc/loadavg.c
fs/proc/task_mmu.c
fs/quota/dquot.c
fs/super.c
fs/udf/unicode.c
include/drm/drm_hdcp.h
include/linux/backing-dev-defs.h
include/linux/backing-dev.h
include/linux/compiler-clang.h
include/linux/coresight-pmu.h
include/linux/fsnotify_backend.h
include/linux/hid.h
include/linux/if_vlan.h
include/linux/livepatch.h
include/linux/microchipphy.h
include/linux/shrinker.h
include/linux/textsearch.h
include/linux/thread_info.h
include/linux/timekeeping32.h
include/linux/timer.h
include/uapi/linux/perf_event.h
include/uapi/linux/random.h
include/xen/interface/io/sndif.h
kernel/events/callchain.c
kernel/events/core.c
kernel/fork.c
kernel/livepatch/shadow.c
kernel/time/posix-cpu-timers.c
kernel/time/tick-oneshot.c
kernel/time/timekeeping.c
kernel/trace/trace_kprobe.c
lib/textsearch.c
mm/filemap.c
mm/huge_memory.c
mm/memcontrol.c
mm/migrate.c
mm/page-writeback.c
mm/rmap.c
mm/vmscan.c
net/caif/chnl_net.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/neighbour.c
net/dns_resolver/dns_key.c
net/ipv4/ip_output.c
net/ipv4/tcp.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_debugfs.c
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
net/llc/af_llc.c
net/packet/af_packet.c
net/qrtr/qrtr.c
net/sctp/ipv6.c
net/smc/af_smc.c
net/strparser/strparser.c
net/sunrpc/rpc_pipe.c
net/tipc/monitor.c
net/tipc/name_table.c
net/tipc/name_table.h
net/tipc/net.c
net/tipc/netlink.c
net/tipc/node.c
net/tipc/socket.c
net/tipc/subscr.c
net/tls/tls_sw.c
net/vmw_vsock/af_vsock.c
samples/livepatch/livepatch-shadow-fix1.c
samples/livepatch/livepatch-shadow-fix2.c
sound/core/rawmidi_compat.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/usb/line6/midi.c
tools/arch/arm/include/uapi/asm/kvm.h
tools/arch/x86/include/asm/required-features.h
tools/arch/x86/include/uapi/asm/kvm.h
tools/include/linux/compiler.h
tools/include/linux/coresight-pmu.h
tools/include/uapi/asm-generic/mman-common.h
tools/include/uapi/linux/bpf.h
tools/include/uapi/linux/if_link.h
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/perf_event.h
tools/include/uapi/sound/asound.h
tools/lib/subcmd/parse-options.c
tools/objtool/Makefile
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-mem.txt
tools/perf/Documentation/perf-sched.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-stat.txt
tools/perf/Makefile.config
tools/perf/arch/arm/include/arch-tests.h [new file with mode: 0644]
tools/perf/arch/arm/tests/Build
tools/perf/arch/arm/tests/arch-tests.c [new file with mode: 0644]
tools/perf/arch/arm/util/auxtrace.c
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/arm/util/cs-etm.h
tools/perf/arch/arm/util/pmu.c
tools/perf/arch/x86/Makefile
tools/perf/arch/x86/annotate/instructions.c
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/builtin-help.c
tools/perf/builtin-mem.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-version.c
tools/perf/perf.c
tools/perf/tests/bpf-script-example.c
tools/perf/tests/bpf-script-test-kbuild.c
tools/perf/tests/builtin-test.c
tools/perf/tests/mmap-basic.c
tools/perf/trace/beauty/mmap.c
tools/perf/ui/browsers/annotate.c
tools/perf/ui/browsers/hists.c
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
tools/perf/util/cs-etm.c
tools/perf/util/cs-etm.h
tools/perf/util/event.c
tools/perf/util/evsel.c
tools/perf/util/generate-cmdlist.sh
tools/perf/util/header.c
tools/perf/util/pmu.c
tools/perf/util/symbol.c
tools/perf/util/syscalltbl.c
tools/perf/util/trace-event-scripting.c
tools/testing/nvdimm/test/nfit.c
tools/testing/selftests/filesystems/Makefile
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/include/vmx.h [new file with mode: 0644]
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/lib/sparsebit.c
tools/testing/selftests/kvm/lib/vmx.c [new file with mode: 0644]
tools/testing/selftests/kvm/vmx_tsc_adjust_test.c [new file with mode: 0644]
tools/testing/selftests/net/Makefile

index ff335f8..92f3000 100644 (file)
@@ -136,6 +136,19 @@ Sorting
 .. kernel-doc:: lib/list_sort.c
    :export:
 
+Text Searching
+--------------
+
+.. kernel-doc:: lib/textsearch.c
+   :doc: ts_intro
+
+.. kernel-doc:: lib/textsearch.c
+   :export:
+
+.. kernel-doc:: include/linux/textsearch.h
+   :functions: textsearch_find textsearch_next \
+               textsearch_get_pattern textsearch_get_pattern_len
+
 UUID/GUID
 ---------
 
index 1b596fd..b957acf 100644 (file)
@@ -49,19 +49,6 @@ on the SoC (only first trip points defined in DT will be configured):
  - samsung,exynos5433-tmu: 8
  - samsung,exynos7-tmu: 8
 
-Following properties are mandatory (depending on SoC):
-- samsung,tmu_gain: Gain value for internal TMU operation.
-- samsung,tmu_reference_voltage: Value of TMU IP block's reference voltage
-- samsung,tmu_noise_cancel_mode: Mode for noise cancellation
-- samsung,tmu_efuse_value: Default level of temperature - it is needed when
-                          in factory fusing produced wrong value
-- samsung,tmu_min_efuse_value: Minimum temperature fused value
-- samsung,tmu_max_efuse_value: Maximum temperature fused value
-- samsung,tmu_first_point_trim: First point trimming value
-- samsung,tmu_second_point_trim: Second point trimming value
-- samsung,tmu_default_temp_offset: Default temperature offset
-- samsung,tmu_cal_type: Callibration type
-
 ** Optional properties:
 
 - vtmu-supply: This entry is optional and provides the regulator node supplying
@@ -78,7 +65,7 @@ Example 1):
                clocks = <&clock 383>;
                clock-names = "tmu_apbif";
                vtmu-supply = <&tmu_regulator_node>;
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Example 2):
@@ -89,7 +76,7 @@ Example 2):
                interrupts = <0 58 0>;
                clocks = <&clock 21>;
                clock-names = "tmu_apbif";
-               #include "exynos5440-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
@@ -99,7 +86,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 184 0>;
                clocks = <&clock 318>, <&clock 318>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
        tmu_cpu3: tmu@1006c000 {
@@ -108,7 +95,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 185 0>;
                clocks = <&clock 318>, <&clock 319>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
        tmu_gpu: tmu@100a0000 {
@@ -117,7 +104,7 @@ Example 3): (In case of Exynos5420 "with misplaced TRIMINFO register")
                interrupts = <0 215 0>;
                clocks = <&clock 319>, <&clock 318>;
                clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-               #include "exynos4412-tmu-sensor-conf.dtsi"
+               #thermal-sensor-cells = <0>;
        };
 
 Note: For multi-instance tmu each instance should have an alias correctly
index 1719d47..cc553f0 100644 (file)
@@ -55,8 +55,7 @@ of heat dissipation). For example a fan's cooling states correspond to
 the different fan speeds possible. Cooling states are referred to by
 single unsigned integers, where larger numbers mean greater heat
 dissipation. The precise set of cooling states associated with a device
-(as referred to by the cooling-min-level and cooling-max-level
-properties) should be defined in a particular device's binding.
+should be defined in a particular device's binding.
 For more examples of cooling devices, refer to the example sections below.
 
 Required properties:
@@ -69,15 +68,6 @@ Required properties:
                        See Cooling device maps section below for more details
                        on how consumers refer to cooling devices.
 
-Optional properties:
-- cooling-min-level:   An integer indicating the smallest
-  Type: unsigned       cooling state accepted. Typically 0.
-  Size: one cell
-
-- cooling-max-level:   An integer indicating the largest
-  Type: unsigned       cooling state accepted.
-  Size: one cell
-
 * Trip points
 
 The trip node is a node to describe a point in the temperature domain
@@ -226,8 +216,6 @@ cpus {
                        396000  950000
                        198000  850000
                >;
-               cooling-min-level = <0>;
-               cooling-max-level = <3>;
                #cooling-cells = <2>; /* min followed by max */
        };
        ...
@@ -241,8 +229,6 @@ cpus {
         */
        fan0: fan@48 {
                ...
-               cooling-min-level = <0>;
-               cooling-max-level = <9>;
                #cooling-cells = <2>; /* min followed by max */
        };
 };
diff --git a/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt b/Documentation/devicetree/bindings/timer/nuvoton,npcm7xx-timer.txt
new file mode 100644 (file)
index 0000000..ea22dfe
--- /dev/null
@@ -0,0 +1,21 @@
+Nuvoton NPCM7xx timer
+
+Nuvoton NPCM7xx have three timer modules, each timer module provides five 24-bit
+timer counters.
+
+Required properties:
+- compatible      : "nuvoton,npcm750-timer" for Poleg NPCM750.
+- reg             : Offset and length of the register set for the device.
+- interrupts      : Contain the timer interrupt with flags for
+                    falling edge.
+- clocks          : phandle of timer reference clock (usually a 25 MHz clock).
+
+Example:
+
+timer@f0008000 {
+    compatible = "nuvoton,npcm750-timer";
+    interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+    reg = <0xf0008000 0x50>;
+    clocks = <&clk NPCM7XX_CLK_TIMER>;
+};
+
index b4aa7dd..f82087b 100644 (file)
@@ -15,7 +15,7 @@ Required properties:
 - interrupts : Should be the clock event device interrupt.
 - clocks :     The clocks provided by the SoC to drive the timer, must contain
                an entry for each entry in clock-names.
-- clock-names : Must include the following entries: "igp" and "per".
+- clock-names : Must include the following entries: "ipg" and "per".
 
 Example:
 tpm5: tpm@40260000 {
index 89c6663..ecc09a7 100644 (file)
@@ -34,9 +34,13 @@ meta-data and shadow-data:
   - data[] - storage for shadow data
 
 It is important to note that the klp_shadow_alloc() and
-klp_shadow_get_or_alloc() calls, described below, store a *copy* of the
-data that the functions are provided.  Callers should provide whatever
-mutual exclusion is required of the shadow data.
+klp_shadow_get_or_alloc() are zeroing the variable by default.
+They also allow to call a custom constructor function when a non-zero
+value is needed. Callers should provide whatever mutual exclusion
+is required.
+
+Note that the constructor is called under klp_shadow_lock spinlock. It allows
+to do actions that can be done only once when a new variable is allocated.
 
 * klp_shadow_get() - retrieve a shadow variable data pointer
   - search hashtable for <obj, id> pair
@@ -47,7 +51,7 @@ mutual exclusion is required of the shadow data.
     - WARN and return NULL
   - if <obj, id> doesn't already exist
     - allocate a new shadow variable
-    - copy data into the new shadow variable
+    - initialize the variable using a custom constructor and data when provided
     - add <obj, id> to the global hashtable
 
 * klp_shadow_get_or_alloc() - get existing or alloc a new shadow variable
@@ -56,16 +60,20 @@ mutual exclusion is required of the shadow data.
     - return existing shadow variable
   - if <obj, id> doesn't already exist
     - allocate a new shadow variable
-    - copy data into the new shadow variable
+    - initialize the variable using a custom constructor and data when provided
     - add <obj, id> pair to the global hashtable
 
 * klp_shadow_free() - detach and free a <obj, id> shadow variable
   - find and remove a <obj, id> reference from global hashtable
-    - if found, free shadow variable
+    - if found
+      - call destructor function if defined
+      - free shadow variable
 
 * klp_shadow_free_all() - detach and free all <*, id> shadow variables
   - find and remove any <*, id> references from global hashtable
-    - if found, free shadow variable
+    - if found
+      - call destructor function if defined
+      - free shadow variable
 
 
 2. Use cases
@@ -107,7 +115,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp);
 
        /* Attach a corresponding shadow variable, then initialize it */
-       ps_lock = klp_shadow_alloc(sta, PS_LOCK, NULL, sizeof(*ps_lock), gfp);
+       ps_lock = klp_shadow_alloc(sta, PS_LOCK, sizeof(*ps_lock), gfp,
+                                  NULL, NULL);
        if (!ps_lock)
                goto shadow_fail;
        spin_lock_init(ps_lock);
@@ -131,7 +140,7 @@ variable:
 
 void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
 {
-       klp_shadow_free(sta, PS_LOCK);
+       klp_shadow_free(sta, PS_LOCK, NULL);
        kfree(sta);
        ...
 
@@ -148,16 +157,24 @@ shadow variables to parents already in-flight.
 For commit 1d147bfa6429, a good spot to allocate a shadow spinlock is
 inside ieee80211_sta_ps_deliver_wakeup():
 
+int ps_lock_shadow_ctor(void *obj, void *shadow_data, void *ctor_data)
+{
+       spinlock_t *lock = shadow_data;
+
+       spin_lock_init(lock);
+       return 0;
+}
+
 #define PS_LOCK 1
 void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 {
-       DEFINE_SPINLOCK(ps_lock_fallback);
        spinlock_t *ps_lock;
 
        /* sync with ieee80211_tx_h_unicast_ps_buf */
        ps_lock = klp_shadow_get_or_alloc(sta, PS_LOCK,
-                       &ps_lock_fallback, sizeof(ps_lock_fallback),
-                       GFP_ATOMIC);
+                       sizeof(*ps_lock), GFP_ATOMIC,
+                       ps_lock_shadow_ctor, NULL);
+
        if (ps_lock)
                spin_lock(ps_lock);
        ...
index a4508ec..fd55c7d 100644 (file)
@@ -169,7 +169,7 @@ access to BPF code as well.
 BPF engine and instruction set
 ------------------------------
 
-Under tools/net/ there's a small helper tool called bpf_asm which can
+Under tools/bpf/ there's a small helper tool called bpf_asm which can
 be used to write low-level filters for example scenarios mentioned in the
 previous section. Asm-like syntax mentioned here has been implemented in
 bpf_asm and will be used for further explanations (instead of dealing with
@@ -359,7 +359,7 @@ $ ./bpf_asm -c foo
 In particular, as usage with xt_bpf or cls_bpf can result in more complex BPF
 filters that might not be obvious at first, it's good to test filters before
 attaching to a live system. For that purpose, there's a small tool called
-bpf_dbg under tools/net/ in the kernel source directory. This debugger allows
+bpf_dbg under tools/bpf/ in the kernel source directory. This debugger allows
 for testing BPF filters against given pcap files, single stepping through the
 BPF code on the pcap's packets and to do BPF machine register dumps.
 
@@ -483,7 +483,7 @@ Example output from dmesg:
 [ 3389.935851] JIT code: 00000030: 00 e8 28 94 ff e0 83 f8 01 75 07 b8 ff ff 00 00
 [ 3389.935852] JIT code: 00000040: eb 02 31 c0 c9 c3
 
-In the kernel source tree under tools/net/, there's bpf_jit_disasm for
+In the kernel source tree under tools/bpf/, there's bpf_jit_disasm for
 generating disassembly out of the kernel log's hexdump:
 
 # ./bpf_jit_disasm
index 5dc1a04..b583a73 100644 (file)
@@ -1390,26 +1390,26 @@ mld_qrv - INTEGER
        Default: 2 (as specified by RFC3810 9.1)
        Minimum: 1 (as specified by RFC6636 4.5)
 
-max_dst_opts_cnt - INTEGER
+max_dst_opts_number - INTEGER
        Maximum number of non-padding TLVs allowed in a Destination
        options extension header. If this value is less than zero
        then unknown options are disallowed and the number of known
        TLVs allowed is the absolute value of this number.
        Default: 8
 
-max_hbh_opts_cnt - INTEGER
+max_hbh_opts_number - INTEGER
        Maximum number of non-padding TLVs allowed in a Hop-by-Hop
        options extension header. If this value is less than zero
        then unknown options are disallowed and the number of known
        TLVs allowed is the absolute value of this number.
        Default: 8
 
-max dst_opts_len - INTEGER
+max_dst_opts_length - INTEGER
        Maximum length allowed for a Destination options extension
        header.
        Default: INT_MAX (unlimited)
 
-max hbh_opts_len - INTEGER
+max_hbh_length - INTEGER
        Maximum length allowed for a Hop-by-Hop options extension
        header.
        Default: INT_MAX (unlimited)
index 89b8ab9..cc9832d 100644 (file)
@@ -1373,7 +1373,8 @@ F:        arch/arm/mach-ebsa110/
 F:     drivers/net/ethernet/amd/am79c961a.*
 
 ARM/ENERGY MICRO (SILICON LABS) EFM32 SUPPORT
-M:     Uwe Kleine-König <kernel@pengutronix.de>
+M:     Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 N:     efm32
@@ -1401,7 +1402,8 @@ F:        arch/arm/mach-footbridge/
 
 ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
 M:     Shawn Guo <shawnguo@kernel.org>
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 R:     Fabio Estevam <fabio.estevam@nxp.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -1416,7 +1418,8 @@ F:        include/soc/imx/
 
 ARM/FREESCALE VYBRID ARM ARCHITECTURE
 M:     Shawn Guo <shawnguo@kernel.org>
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 R:     Stefan Agner <stefan@agner.ch>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -4245,6 +4248,9 @@ F:        include/trace/events/fs_dax.h
 
 DEVICE DIRECT ACCESS (DAX)
 M:     Dan Williams <dan.j.williams@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
 L:     linux-nvdimm@lists.01.org
 S:     Supported
 F:     drivers/dax/
@@ -5652,7 +5658,8 @@ F:        drivers/net/ethernet/freescale/fec.h
 F:     Documentation/devicetree/bindings/net/fsl-fec.txt
 
 FREESCALE IMX / MXC FRAMEBUFFER DRIVER
-M:     Sascha Hauer <kernel@pengutronix.de>
+M:     Sascha Hauer <s.hauer@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 L:     linux-fbdev@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -5784,6 +5791,14 @@ F:       fs/crypto/
 F:     include/linux/fscrypt*.h
 F:     Documentation/filesystems/fscrypt.rst
 
+FSNOTIFY: FILESYSTEM NOTIFICATION INFRASTRUCTURE
+M:     Jan Kara <jack@suse.cz>
+R:     Amir Goldstein <amir73il@gmail.com>
+L:     linux-fsdevel@vger.kernel.org
+S:     Maintained
+F:     fs/notify/
+F:     include/linux/fsnotify*.h
+
 FUJITSU LAPTOP EXTRAS
 M:     Jonathan Woithe <jwoithe@just42.net>
 L:     platform-driver-x86@vger.kernel.org
@@ -6256,7 +6271,7 @@ S:        Odd Fixes
 F:     drivers/media/usb/hdpvr/
 
 HEWLETT PACKARD ENTERPRISE ILO NMI WATCHDOG DRIVER
-M:     Jimmy Vance <jimmy.vance@hpe.com>
+M:     Jerry Hoemann <jerry.hoemann@hpe.com>
 S:     Supported
 F:     Documentation/watchdog/hpwdt.txt
 F:     drivers/watchdog/hpwdt.c
@@ -8048,6 +8063,9 @@ F:        tools/lib/lockdep/
 
 LIBNVDIMM BLK: MMIO-APERTURE DRIVER
 M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8056,6 +8074,9 @@ F:        drivers/nvdimm/region_devs.c
 
 LIBNVDIMM BTT: BLOCK TRANSLATION TABLE
 M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8063,6 +8084,9 @@ F:        drivers/nvdimm/btt*
 
 LIBNVDIMM PMEM: PERSISTENT MEMORY DRIVER
 M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Dan Williams <dan.j.williams@intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 S:     Supported
@@ -8078,6 +8102,9 @@ F:        Documentation/devicetree/bindings/pmem/pmem-region.txt
 
 LIBNVDIMM: NON-VOLATILE MEMORY DEVICE SUBSYSTEM
 M:     Dan Williams <dan.j.williams@intel.com>
+M:     Ross Zwisler <ross.zwisler@linux.intel.com>
+M:     Vishal Verma <vishal.l.verma@intel.com>
+M:     Dave Jiang <dave.jiang@intel.com>
 L:     linux-nvdimm@lists.01.org
 Q:     https://patchwork.kernel.org/project/linux-nvdimm/list/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git
@@ -9765,6 +9792,7 @@ F:        include/uapi/linux/net_namespace.h
 F:     tools/testing/selftests/net/
 F:     lib/net_utils.c
 F:     lib/random32.c
+F:     Documentation/networking/
 
 NETWORKING [IPSEC]
 M:     Steffen Klassert <steffen.klassert@secunet.com>
@@ -12816,7 +12844,8 @@ F:      include/linux/siphash.h
 
 SIOX
 M:     Gavin Schenk <g.schenk@eckelmann.de>
-M:     Uwe Kleine-König <kernel@pengutronix.de>
+M:     Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+R:     Pengutronix Kernel Team <kernel@pengutronix.de>
 S:     Supported
 F:     drivers/siox/*
 F:     include/trace/events/siox.h
index 74567b0..83b6c54 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 4
-PATCHLEVEL = 16
+PATCHLEVEL = 17
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc2
 NAME = Fearless Coyote
 
 # *DOCUMENTATION*
index ba964da..1cb2749 100644 (file)
@@ -366,7 +366,7 @@ void force_signal_inject(int signal, int code, unsigned long address)
        }
 
        /* Force signals we don't understand to SIGKILL */
-       if (WARN_ON(signal != SIGKILL ||
+       if (WARN_ON(signal != SIGKILL &&
                    siginfo_layout(signal, code) != SIL_FAULT)) {
                signal = SIGKILL;
        }
index dabfc1e..1214587 100644 (file)
@@ -204,7 +204,7 @@ void __init kasan_init(void)
        clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
        kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
-                          pfn_to_nid(virt_to_pfn(lm_alias(_text))));
+                          early_pfn_to_nid(virt_to_pfn(lm_alias(_text))));
 
        kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
                                   (void *)mod_shadow_start);
@@ -224,7 +224,7 @@ void __init kasan_init(void)
 
                kasan_map_populate((unsigned long)kasan_mem_to_shadow(start),
                                   (unsigned long)kasan_mem_to_shadow(end),
-                                  pfn_to_nid(virt_to_pfn(start)));
+                                  early_pfn_to_nid(virt_to_pfn(start)));
        }
 
        /*
index 1bd1054..65af3f6 100644 (file)
@@ -51,6 +51,8 @@
                ranges = <0x02000000 0 0x40000000
                          0x40000000 0 0x40000000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci0_intc 1>,
                                <0 0 0 2 &pci0_intc 2>,
@@ -79,6 +81,8 @@
                ranges = <0x02000000 0 0x20000000
                          0x20000000 0 0x20000000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci1_intc 1>,
                                <0 0 0 2 &pci1_intc 2>,
                ranges = <0x02000000 0 0x16000000
                          0x16000000 0 0x100000>;
 
+               bus-range = <0x00 0xff>;
+
                interrupt-map-mask = <0 0 0 7>;
                interrupt-map = <0 0 0 1 &pci2_intc 1>,
                                <0 0 0 2 &pci2_intc 2>,
index 0cbf3af..a7d0b83 100644 (file)
@@ -307,7 +307,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 #if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT)
 #define war_io_reorder_wmb()           wmb()
 #else
-#define war_io_reorder_wmb()           do { } while (0)
+#define war_io_reorder_wmb()           barrier()
 #endif
 
 #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)                    \
@@ -377,6 +377,8 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)        \
                BUG();                                                  \
        }                                                               \
                                                                        \
+       /* prevent prefetching of coherent DMA data prematurely */      \
+       rmb();                                                          \
        return pfx##ioswab##bwlq(__mem, __val);                         \
 }
 
index b713069..0662901 100644 (file)
@@ -654,6 +654,13 @@ __clear_user(void __user *addr, __kernel_size_t size)
 {
        __kernel_size_t res;
 
+#ifdef CONFIG_CPU_MICROMIPS
+/* micromips memset / bzero also clobbers t7 & t8 */
+#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31"
+#else
+#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
+#endif /* CONFIG_CPU_MICROMIPS */
+
        if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
@@ -663,7 +670,7 @@ __clear_user(void __user *addr, __kernel_size_t size)
                        "move\t%0, $6"
                        : "=r" (res)
                        : "r" (addr), "r" (size)
-                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+                       : bzero_clobbers);
        } else {
                might_fault();
                __asm__ __volatile__(
@@ -674,7 +681,7 @@ __clear_user(void __user *addr, __kernel_size_t size)
                        "move\t%0, $6"
                        : "=r" (res)
                        : "r" (addr), "r" (size)
-                       : "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
+                       : bzero_clobbers);
        }
 
        return res;
index a145666..f732797 100644 (file)
 1:     PTR_ADDIU       a0, 1                   /* fill bytewise */
        R10KCBARRIER(0(ra))
        bne             t1, a0, 1b
-       sb              a1, -1(a0)
+        EX(sb, a1, -1(a0), .Lsmall_fixup\@)
 
 2:     jr              ra                      /* done */
        move            a2, zero
        PTR_L           t0, TI_TASK($28)
        andi            a2, STORMASK
        LONG_L          t0, THREAD_BUADDR(t0)
-       LONG_ADDU       a2, t1
+       LONG_ADDU       a2, a0
        jr              ra
        LONG_SUBU       a2, t0
 
 .Llast_fixup\@:
        jr              ra
-       andi            v1, a2, STORMASK
+        nop
+
+.Lsmall_fixup\@:
+       PTR_SUBU        a2, t1, a0
+       jr              ra
+        PTR_ADDIU      a2, 1
 
        .endm
 
index eafd06a..e5de34d 100644 (file)
@@ -23,7 +23,7 @@ obj-$(CONFIG_SMP)     += smp.o
 obj-$(CONFIG_PA11)     += pci-dma.o
 obj-$(CONFIG_PCI)      += pci.o
 obj-$(CONFIG_MODULES)  += module.o
-obj-$(CONFIG_64BIT)    += binfmt_elf32.o sys_parisc32.o signal32.o
+obj-$(CONFIG_64BIT)    += sys_parisc32.o signal32.o
 obj-$(CONFIG_STACKTRACE)+= stacktrace.o
 obj-$(CONFIG_AUDIT)    += audit.o
 obj64-$(CONFIG_AUDIT)  += compat_audit.o
index 2d4956e..ee5a67d 100644 (file)
@@ -807,7 +807,8 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev)
        eeh_ops->write_config(pdn, 15*4, 4, edev->config_space[15]);
 
        /* PCI Command: 0x4 */
-       eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1]);
+       eeh_ops->write_config(pdn, PCI_COMMAND, 4, edev->config_space[1] |
+                             PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 
        /* Check the PCIe link is ready */
        eeh_bridge_check_link(edev);
index 79d0054..e734f6e 100644 (file)
@@ -553,12 +553,12 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
        lbz     r0,HSTATE_HWTHREAD_STATE(r13)
        cmpwi   r0,KVM_HWTHREAD_IN_KERNEL
-       beq     1f
+       beq     0f
        li      r0,KVM_HWTHREAD_IN_KERNEL
        stb     r0,HSTATE_HWTHREAD_STATE(r13)
        /* Order setting hwthread_state vs. testing hwthread_req */
        sync
-       lbz     r0,HSTATE_HWTHREAD_REQ(r13)
+0:     lbz     r0,HSTATE_HWTHREAD_REQ(r13)
        cmpwi   r0,0
        beq     1f
        b       kvm_start_guest
index 44c30dd..b78f142 100644 (file)
@@ -890,6 +890,17 @@ static void __ref init_fallback_flush(void)
                return;
 
        l1d_size = ppc64_caches.l1d.size;
+
+       /*
+        * If there is no d-cache-size property in the device tree, l1d_size
+        * could be zero. That leads to the loop in the asm wrapping around to
+        * 2^64-1, and then walking off the end of the fallback area and
+        * eventually causing a page fault which is fatal. Just default to
+        * something vaguely sane.
+        */
+       if (!l1d_size)
+               l1d_size = (64 * 1024);
+
        limit = min(ppc64_bolted_size(), ppc64_rma_size);
 
        /*
index 35f80ab..288fe4f 100644 (file)
@@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest,
                unsigned int *target = (unsigned int *)branch_target(src);
 
                /* Branch within the section doesn't need translating */
-               if (target < alt_start || target >= alt_end) {
+               if (target < alt_start || target > alt_end) {
                        instr = translate_branch(dest, src);
                        if (!instr)
                                return 1;
index 9033c81..ccc4215 100644 (file)
@@ -1093,7 +1093,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private)
                LOAD_INT(c), LOAD_FRAC(c),
                count_active_contexts(),
                atomic_read(&nr_spu_contexts),
-               idr_get_cursor(&task_active_pid_ns(current)->idr));
+               idr_get_cursor(&task_active_pid_ns(current)->idr) - 1);
        return 0;
 }
 
index d22aeb0..b48454b 100644 (file)
@@ -389,6 +389,10 @@ static void xive_native_setup_cpu(unsigned int cpu, struct xive_cpu *xc)
        if (xive_pool_vps == XIVE_INVALID_VP)
                return;
 
+       /* Check if pool VP already active, if it is, pull it */
+       if (in_be32(xive_tima + TM_QW2_HV_POOL + TM_WORD2) & TM_QW2W2_VP)
+               in_be64(xive_tima + TM_SPC_PULL_POOL_CTX);
+
        /* Enable the pool VP */
        vp = xive_pool_vps + cpu;
        pr_debug("CPU %d setting up pool VP 0x%x\n", cpu, vp);
index 9fdff3f..e63940b 100644 (file)
@@ -8,3 +8,4 @@ obj-$(CONFIG_APPLDATA_BASE)     += appldata/
 obj-y                          += net/
 obj-$(CONFIG_PCI)              += pci/
 obj-$(CONFIG_NUMA)             += numa/
+obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/
index 32a0d5b..199ac3e 100644 (file)
@@ -47,10 +47,6 @@ config PGSTE
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
        def_bool y
 
-config KEXEC
-       def_bool y
-       select KEXEC_CORE
-
 config AUDIT_ARCH
        def_bool y
 
@@ -290,12 +286,12 @@ config MARCH_Z13
          older machines.
 
 config MARCH_Z14
-       bool "IBM z14"
+       bool "IBM z14 ZR1 and z14"
        select HAVE_MARCH_Z14_FEATURES
        help
-         Select this to enable optimizations for IBM z14 (3906 series).
-         The kernel will be slightly faster but will not work on older
-         machines.
+         Select this to enable optimizations for IBM z14 ZR1 and z14 (3907
+         and 3906 series). The kernel will be slightly faster but will not
+         work on older machines.
 
 endchoice
 
@@ -525,6 +521,26 @@ source kernel/Kconfig.preempt
 
 source kernel/Kconfig.hz
 
+config KEXEC
+       def_bool y
+       select KEXEC_CORE
+
+config KEXEC_FILE
+       bool "kexec file based system call"
+       select KEXEC_CORE
+       select BUILD_BIN2C
+       depends on CRYPTO
+       depends on CRYPTO_SHA256
+       depends on CRYPTO_SHA256_S390
+       help
+         Enable the kexec file based system call. In contrast to the normal
+         kexec system call this system call takes file descriptors for the
+         kernel and initramfs as arguments.
+
+config ARCH_HAS_KEXEC_PURGATORY
+       def_bool y
+       depends on KEXEC_FILE
+
 config ARCH_RANDOM
        def_bool y
        prompt "s390 architectural random number generation API"
index da9dad3..d1fa37f 100644 (file)
@@ -3,12 +3,6 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
-COMPILE_VERSION := __linux_compile_version_id__`hostname |  \
-                       tr -c '[0-9A-Za-z]' '_'`__`date | \
-                       tr -c '[0-9A-Za-z]' '_'`_t
-
-ccflags-y  := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
-
 targets := image
 targets += bzImage
 subdir- := compressed
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
new file mode 100644 (file)
index 0000000..6176fe9
--- /dev/null
@@ -0,0 +1,731 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_USERFAULTFD=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_STATIC_KEYS_SELFTEST=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_WBT_SQ=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_IBM_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_LIVEPATCH=y
+CONFIG_TUNE_ZEC12=y
+CONFIG_NR_CPUS=512
+CONFIG_NUMA=y
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_MEM_SOFT_DIRTY=y
+CONFIG_ZSWAP=y
+CONFIG_ZBUD=m
+CONFIG_ZSMALLOC=m
+CONFIG_ZSMALLOC_STAT=y
+CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
+CONFIG_IDLE_PAGE_TRACKING=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_S390=y
+CONFIG_CHSC_SCH=y
+CONFIG_CRASH_DUMP=y
+CONFIG_BINFMT_MISC=m
+CONFIG_HIBERNATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_SMC=m
+CONFIG_SMC_DIAG=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_NET_IPVTI=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_DIAG=m
+CONFIG_INET_UDP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_VTI=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_GRE=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CONNTRACK_TIMEOUT=y
+CONFIG_NF_CONNTRACK_TIMESTAMP=y
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_CT_NETLINK_TIMEOUT=m
+CONFIG_NF_TABLES=m
+CONFIG_NFT_EXTHDR=m
+CONFIG_NFT_META=m
+CONFIG_NFT_CT=m
+CONFIG_NFT_COUNTER=m
+CONFIG_NFT_LOG=m
+CONFIG_NFT_LIMIT=m
+CONFIG_NFT_NAT=m
+CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_SET_BITMAP_IP=m
+CONFIG_IP_SET_BITMAP_IPMAC=m
+CONFIG_IP_SET_BITMAP_PORT=m
+CONFIG_IP_SET_HASH_IP=m
+CONFIG_IP_SET_HASH_IPPORT=m
+CONFIG_IP_SET_HASH_IPPORTIP=m
+CONFIG_IP_SET_HASH_IPPORTNET=m
+CONFIG_IP_SET_HASH_NETPORTNET=m
+CONFIG_IP_SET_HASH_NET=m
+CONFIG_IP_SET_HASH_NETNET=m
+CONFIG_IP_SET_HASH_NETPORT=m
+CONFIG_IP_SET_HASH_NETIFACE=m
+CONFIG_IP_SET_LIST_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_VS_PE_SIP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_TABLES_IPV4=m
+CONFIG_NFT_CHAIN_ROUTE_IPV4=m
+CONFIG_NF_TABLES_ARP=m
+CONFIG_NFT_CHAIN_NAT_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_NF_TABLES_IPV6=m
+CONFIG_NFT_CHAIN_ROUTE_IPV6=m
+CONFIG_NFT_CHAIN_NAT_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_RDS=m
+CONFIG_RDS_RDMA=m
+CONFIG_RDS_TCP=m
+CONFIG_RDS_DEBUG=y
+CONFIG_L2TP=m
+CONFIG_L2TP_DEBUGFS=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_CHOKE=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_PLUG=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_ACT_CSUM=m
+CONFIG_DNS_RESOLVER=y
+CONFIG_OPENVSWITCH=m
+CONFIG_NETLINK_DIAG=m
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_BPF_JIT=y
+CONFIG_NET_PKTGEN=m
+CONFIG_DEVTMPFS=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_CONNECTOR=y
+CONFIG_ZRAM=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_DRBD=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
+CONFIG_BLK_DEV_NVME=m
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_GENWQE=m
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_ENCLOSURE=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_ZFCP=y
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_LOG_USERSPACE=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_DELAY=m
+CONFIG_DM_UEVENT=y
+CONFIG_DM_FLAKEY=m
+CONFIG_DM_VERITY=m
+CONFIG_DM_SWITCH=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=m
+CONFIG_EQUALIZER=m
+CONFIG_IFB=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_VXLAN=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+CONFIG_MLX4_EN=m
+CONFIG_MLX5_CORE=m
+CONFIG_MLX5_CORE_EN=y
+# CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_RAW_DRIVER=m
+CONFIG_HANGCHECK_TIMER=m
+CONFIG_TN3270_FS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_DIAG288_WATCHDOG=m
+CONFIG_DRM=y
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_ACCESS=m
+CONFIG_MLX4_INFINIBAND=m
+CONFIG_MLX5_INFINIBAND=m
+CONFIG_VFIO=m
+CONFIG_VFIO_PCI=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_XFS_DEBUG=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=y
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_BTRFS_DEBUG=y
+CONFIG_NILFS2_FS=m
+CONFIG_FS_DAX=y
+CONFIG_EXPORTFS_BLOCK_OPS=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_QUOTA_DEBUG=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_OVERLAY_FS=m
+CONFIG_FSCACHE=m
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_NTFS_RW=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=m
+CONFIG_NFS_SWAP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_V4_SECURITY_LABEL=y
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DLM=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_FRAME_WARN=1024
+CONFIG_READABLE_ASM=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_RODATA_TEST=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_SELFTEST=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_WORK=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_SLUB_STATS=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_VM=y
+CONFIG_DEBUG_VM_VMACACHE=y
+CONFIG_DEBUG_VM_RB=y
+CONFIG_DEBUG_VM_PGFLAGS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
+CONFIG_DEBUG_PER_CPU_MAPS=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_DEBUG_TIMEKEEPING=y
+CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCK_STAT=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_DEBUG_CREDENTIALS=y
+CONFIG_RCU_TORTURE_TEST=m
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+CONFIG_NOTIFIER_ERROR_INJECTION=m
+CONFIG_PM_NOTIFIER_ERROR_INJECT=m
+CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAILSLAB=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAIL_MAKE_REQUEST=y
+CONFIG_FAIL_IO_TIMEOUT=y
+CONFIG_FAIL_FUTEX=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_LATENCYTOP=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_STACK_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_HIST_TRIGGERS=y
+CONFIG_DMA_API_DEBUG=y
+CONFIG_LKDTM=m
+CONFIG_TEST_LIST_SORT=y
+CONFIG_TEST_SORT=y
+CONFIG_KPROBES_SANITY_TEST=y
+CONFIG_RBTREE_TEST=y
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_PERCPU_TEST=m
+CONFIG_ATOMIC64_SELFTEST=y
+CONFIG_TEST_BPF=m
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_S390_PTDUMP=y
+CONFIG_PERSISTENT_KEYRINGS=y
+CONFIG_BIG_KEYS=y
+CONFIG_ENCRYPTED_KEYS=m
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_IMA=y
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
+CONFIG_IMA_WRITE_POLICY=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_DH=m
+CONFIG_CRYPTO_ECDH=m
+CONFIG_CRYPTO_USER=m
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_MCRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_KEYWRAP=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_SHA3=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES_TI=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_842=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=m
+CONFIG_ZCRYPT=m
+CONFIG_PKEY=m
+CONFIG_CRYPTO_PAES_S390=m
+CONFIG_CRYPTO_SHA1_S390=m
+CONFIG_CRYPTO_SHA256_S390=m
+CONFIG_CRYPTO_SHA512_S390=m
+CONFIG_CRYPTO_DES_S390=m
+CONFIG_CRYPTO_AES_S390=m
+CONFIG_CRYPTO_GHASH_S390=m
+CONFIG_CRYPTO_CRC32_S390=y
+CONFIG_PKCS7_MESSAGE_PARSER=y
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_CRC7=m
+CONFIG_CRC8=m
+CONFIG_RANDOM32_SELFTEST=y
+CONFIG_CORDIC=m
+CONFIG_CMM=m
+CONFIG_APPLDATA_BASE=y
+CONFIG_KVM=m
+CONFIG_KVM_S390_UCONTROL=y
+CONFIG_VHOST_NET=m
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig
deleted file mode 100644 (file)
index 5af8458..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_AUDIT=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NUMA_BALANCING=y
-CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
-CONFIG_BLK_CGROUP=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_CGROUP_PIDS=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_HUGETLB=y
-CONFIG_CPUSETS=y
-CONFIG_CGROUP_DEVICE=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_SCHED_AUTOGROUP=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_USERFAULTFD=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_JUMP_LABEL=y
-CONFIG_STATIC_KEYS_SELFTEST=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_THROTTLING=y
-CONFIG_BLK_WBT=y
-CONFIG_BLK_WBT_SQ=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_LIVEPATCH=y
-CONFIG_TUNE_ZEC12=y
-CONFIG_NR_CPUS=256
-CONFIG_NUMA=y
-CONFIG_PREEMPT=y
-CONFIG_HZ_100=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_KSM=y
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CLEANCACHE=y
-CONFIG_FRONTSWAP=y
-CONFIG_CMA_DEBUG=y
-CONFIG_CMA_DEBUGFS=y
-CONFIG_MEM_SOFT_DIRTY=y
-CONFIG_ZSWAP=y
-CONFIG_ZBUD=m
-CONFIG_ZSMALLOC=m
-CONFIG_ZSMALLOC_STAT=y
-CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
-CONFIG_IDLE_PAGE_TRACKING=y
-CONFIG_PCI=y
-CONFIG_PCI_DEBUG=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_S390=y
-CONFIG_CHSC_SCH=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HIBERNATION=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_PACKET_DIAG=m
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=m
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_SMC=m
-CONFIG_SMC_DIAG=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_NET_IPVTI=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_INET_UDP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_VTI=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_GRE=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CONNTRACK_TIMEOUT=y
-CONFIG_NF_CONNTRACK_TIMESTAMP=y
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_SNMP=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NF_CT_NETLINK_TIMEOUT=m
-CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
-CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
-CONFIG_NFT_LOG=m
-CONFIG_NFT_LIMIT=m
-CONFIG_NFT_NAT=m
-CONFIG_NFT_COMPAT=m
-CONFIG_NFT_HASH=m
-CONFIG_NETFILTER_XT_SET=m
-CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_HMARK=m
-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
-CONFIG_NETFILTER_XT_TARGET_LOG=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TEE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
-CONFIG_NETFILTER_XT_MATCH_BPF=m
-CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_CPU=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_IPVS=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_NFACCT=m
-CONFIG_NETFILTER_XT_MATCH_OSF=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_SET=m
-CONFIG_IP_SET_BITMAP_IP=m
-CONFIG_IP_SET_BITMAP_IPMAC=m
-CONFIG_IP_SET_BITMAP_PORT=m
-CONFIG_IP_SET_HASH_IP=m
-CONFIG_IP_SET_HASH_IPPORT=m
-CONFIG_IP_SET_HASH_IPPORTIP=m
-CONFIG_IP_SET_HASH_IPPORTNET=m
-CONFIG_IP_SET_HASH_NETPORTNET=m
-CONFIG_IP_SET_HASH_NET=m
-CONFIG_IP_SET_HASH_NETNET=m
-CONFIG_IP_SET_HASH_NETPORT=m
-CONFIG_IP_SET_HASH_NETIFACE=m
-CONFIG_IP_SET_LIST_SET=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-CONFIG_IP_VS_FTP=m
-CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_CHAIN_ROUTE_IPV4=m
-CONFIG_NF_TABLES_ARP=m
-CONFIG_NFT_CHAIN_NAT_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_RPFILTER=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_NF_TABLES_IPV6=m
-CONFIG_NFT_CHAIN_ROUTE_IPV6=m
-CONFIG_NFT_CHAIN_NAT_IPV6=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RPFILTER=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_SECURITY=m
-CONFIG_IP6_NF_NAT=m
-CONFIG_IP6_NF_TARGET_MASQUERADE=m
-CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
-CONFIG_RDS=m
-CONFIG_RDS_RDMA=m
-CONFIG_RDS_TCP=m
-CONFIG_RDS_DEBUG=y
-CONFIG_L2TP=m
-CONFIG_L2TP_DEBUGFS=m
-CONFIG_L2TP_V3=y
-CONFIG_L2TP_IP=m
-CONFIG_L2TP_ETH=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFB=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_DRR=m
-CONFIG_NET_SCH_MQPRIO=m
-CONFIG_NET_SCH_CHOKE=m
-CONFIG_NET_SCH_QFQ=m
-CONFIG_NET_SCH_CODEL=m
-CONFIG_NET_SCH_FQ_CODEL=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_SCH_PLUG=m
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
-CONFIG_NET_CLS_CGROUP=y
-CONFIG_NET_CLS_BPF=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_ACT_SKBEDIT=m
-CONFIG_NET_ACT_CSUM=m
-CONFIG_DNS_RESOLVER=y
-CONFIG_NETLINK_DIAG=m
-CONFIG_CGROUP_NET_PRIO=y
-CONFIG_BPF_JIT=y
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-CONFIG_DEVTMPFS=y
-CONFIG_DMA_CMA=y
-CONFIG_CMA_SIZE_MBYTES=0
-CONFIG_CONNECTOR=y
-CONFIG_ZRAM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_DRBD=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_BLK_DEV_RBD=m
-CONFIG_ENCLOSURE_SERVICES=m
-CONFIG_GENWQE=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_ENCLOSURE=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_ISCSI_TCP=m
-CONFIG_SCSI_DEBUG=m
-CONFIG_ZFCP=y
-CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=y
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_THIN_PROVISIONING=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_RAID=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-CONFIG_DM_DELAY=m
-CONFIG_DM_UEVENT=y
-CONFIG_DM_FLAKEY=m
-CONFIG_DM_VERITY=m
-CONFIG_DM_SWITCH=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_IFB=m
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_VXLAN=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_VIRTIO_NET=m
-CONFIG_NLMON=m
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-CONFIG_MLX4_EN=m
-CONFIG_MLX5_CORE=m
-CONFIG_MLX5_CORE_EN=y
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPPOL2TP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_RAW_DRIVER=m
-CONFIG_HANGCHECK_TIMER=m
-CONFIG_TN3270_FS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_DIAG288_WATCHDOG=m
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_MLX5_INFINIBAND=m
-CONFIG_VFIO=m
-CONFIG_VFIO_PCI=m
-CONFIG_VIRTIO_BALLOON=m
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
-CONFIG_JBD2_DEBUG=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-CONFIG_JFS_STATISTICS=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_XFS_DEBUG=y
-CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
-CONFIG_BTRFS_FS=y
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_BTRFS_DEBUG=y
-CONFIG_NILFS2_FS=m
-CONFIG_FS_DAX=y
-CONFIG_EXPORTFS_BLOCK_OPS=y
-CONFIG_FANOTIFY=y
-CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QUOTA_DEBUG=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=y
-CONFIG_CUSE=m
-CONFIG_OVERLAY_FS=m
-CONFIG_FSCACHE=m
-CONFIG_CACHEFILES=m
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=m
-CONFIG_ECRYPT_FS=m
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_XATTR=y
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_ROMFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=m
-CONFIG_NFS_SWAP=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_V4_SECURITY_LABEL=y
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_UPCALL=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG is not set
-CONFIG_CIFS_DFS_UPCALL=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-CONFIG_PRINTK_TIME=y
-CONFIG_DYNAMIC_DEBUG=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-CONFIG_FRAME_WARN=1024
-CONFIG_READABLE_ASM=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_DEBUG_SECTION_MISMATCH=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_DEBUG_RODATA_TEST=y
-CONFIG_DEBUG_OBJECTS=y
-CONFIG_DEBUG_OBJECTS_SELFTEST=y
-CONFIG_DEBUG_OBJECTS_FREE=y
-CONFIG_DEBUG_OBJECTS_TIMERS=y
-CONFIG_DEBUG_OBJECTS_WORK=y
-CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
-CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
-CONFIG_SLUB_DEBUG_ON=y
-CONFIG_SLUB_STATS=y
-CONFIG_DEBUG_STACK_USAGE=y
-CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_VM_VMACACHE=y
-CONFIG_DEBUG_VM_RB=y
-CONFIG_DEBUG_VM_PGFLAGS=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m
-CONFIG_DEBUG_PER_CPU_MAPS=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_LOCK_STAT=y
-CONFIG_DEBUG_LOCKDEP=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_DEBUG_LOCKING_API_SELFTESTS=y
-CONFIG_DEBUG_SG=y
-CONFIG_DEBUG_NOTIFIERS=y
-CONFIG_DEBUG_CREDENTIALS=y
-CONFIG_RCU_TORTURE_TEST=m
-CONFIG_RCU_CPU_STALL_TIMEOUT=300
-CONFIG_NOTIFIER_ERROR_INJECTION=m
-CONFIG_PM_NOTIFIER_ERROR_INJECT=m
-CONFIG_NETDEV_NOTIFIER_ERROR_INJECT=m
-CONFIG_FAULT_INJECTION=y
-CONFIG_FAILSLAB=y
-CONFIG_FAIL_PAGE_ALLOC=y
-CONFIG_FAIL_MAKE_REQUEST=y
-CONFIG_FAIL_IO_TIMEOUT=y
-CONFIG_FAIL_FUTEX=y
-CONFIG_FAULT_INJECTION_DEBUG_FS=y
-CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
-CONFIG_LATENCYTOP=y
-CONFIG_IRQSOFF_TRACER=y
-CONFIG_PREEMPT_TRACER=y
-CONFIG_SCHED_TRACER=y
-CONFIG_FTRACE_SYSCALLS=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_FUNCTION_PROFILER=y
-CONFIG_HIST_TRIGGERS=y
-CONFIG_DMA_API_DEBUG=y
-CONFIG_LKDTM=m
-CONFIG_TEST_LIST_SORT=y
-CONFIG_TEST_SORT=y
-CONFIG_KPROBES_SANITY_TEST=y
-CONFIG_RBTREE_TEST=y
-CONFIG_INTERVAL_TREE_TEST=m
-CONFIG_PERCPU_TEST=m
-CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_TEST_BPF=m
-CONFIG_BUG_ON_DATA_CORRUPTION=y
-CONFIG_S390_PTDUMP=y
-CONFIG_ENCRYPTED_KEYS=m
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_FORTIFY_SOURCE=y
-CONFIG_SECURITY_SELINUX=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
-CONFIG_SECURITY_SELINUX_DISABLE=y
-CONFIG_IMA=y
-CONFIG_IMA_APPRAISE=y
-CONFIG_CRYPTO_RSA=m
-CONFIG_CRYPTO_DH=m
-CONFIG_CRYPTO_ECDH=m
-CONFIG_CRYPTO_USER=m
-CONFIG_CRYPTO_PCRYPT=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_MCRYPTD=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_KEYWRAP=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_VMAC=m
-CONFIG_CRYPTO_CRC32=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES_TI=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_842=m
-CONFIG_CRYPTO_LZ4=m
-CONFIG_CRYPTO_LZ4HC=m
-CONFIG_CRYPTO_ANSI_CPRNG=m
-CONFIG_CRYPTO_USER_API_HASH=m
-CONFIG_CRYPTO_USER_API_SKCIPHER=m
-CONFIG_CRYPTO_USER_API_RNG=m
-CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_ZCRYPT=m
-CONFIG_PKEY=m
-CONFIG_CRYPTO_PAES_S390=m
-CONFIG_CRYPTO_SHA1_S390=m
-CONFIG_CRYPTO_SHA256_S390=m
-CONFIG_CRYPTO_SHA512_S390=m
-CONFIG_CRYPTO_DES_S390=m
-CONFIG_CRYPTO_AES_S390=m
-CONFIG_CRYPTO_GHASH_S390=m
-CONFIG_CRYPTO_CRC32_S390=y
-CONFIG_ASYMMETRIC_KEY_TYPE=y
-CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
-CONFIG_X509_CERTIFICATE_PARSER=m
-CONFIG_CRC7=m
-CONFIG_CRC8=m
-CONFIG_RANDOM32_SELFTEST=y
-CONFIG_CORDIC=m
-CONFIG_CMM=m
-CONFIG_APPLDATA_BASE=y
-CONFIG_KVM=m
-CONFIG_KVM_S390_UCONTROL=y
-CONFIG_VHOST_NET=m
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig
deleted file mode 100644 (file)
index d52eafe..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_AUDIT=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_NUMA_BALANCING=y
-# CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set
-CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
-CONFIG_BLK_CGROUP=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_CGROUP_PIDS=y
-CONFIG_CGROUP_FREEZER=y
-CONFIG_CGROUP_HUGETLB=y
-CONFIG_CPUSETS=y
-CONFIG_CGROUP_DEVICE=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_SCHED_AUTOGROUP=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_BPF_SYSCALL=y
-CONFIG_USERFAULTFD=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_JUMP_LABEL=y
-CONFIG_GCOV_KERNEL=y
-CONFIG_GCOV_PROFILE_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_BLK_DEV_THROTTLING=y
-CONFIG_BLK_WBT=y
-CONFIG_BLK_WBT_SQ=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IBM_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_CFQ_GROUP_IOSCHED=y
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_LIVEPATCH=y
-CONFIG_TUNE_ZEC12=y
-CONFIG_NR_CPUS=512
-CONFIG_NUMA=y
-CONFIG_HZ_100=y
-CONFIG_MEMORY_HOTPLUG=y
-CONFIG_MEMORY_HOTREMOVE=y
-CONFIG_KSM=y
-CONFIG_TRANSPARENT_HUGEPAGE=y
-CONFIG_CLEANCACHE=y
-CONFIG_FRONTSWAP=y
-CONFIG_MEM_SOFT_DIRTY=y
-CONFIG_ZSWAP=y
-CONFIG_ZBUD=m
-CONFIG_ZSMALLOC=m
-CONFIG_ZSMALLOC_STAT=y
-CONFIG_DEFERRED_STRUCT_PAGE_INIT=y
-CONFIG_IDLE_PAGE_TRACKING=y
-CONFIG_PCI=y
-CONFIG_HOTPLUG_PCI=y
-CONFIG_HOTPLUG_PCI_S390=y
-CONFIG_CHSC_SCH=y
-CONFIG_CRASH_DUMP=y
-CONFIG_BINFMT_MISC=m
-CONFIG_HIBERNATION=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_PACKET_DIAG=m
-CONFIG_UNIX=y
-CONFIG_UNIX_DIAG=m
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_SMC=m
-CONFIG_SMC_DIAG=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE_DEMUX=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_NET_IPVTI=m
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-CONFIG_INET_UDP_DIAG=m
-CONFIG_TCP_CONG_ADVANCED=y
-CONFIG_TCP_CONG_HSTCP=m
-CONFIG_TCP_CONG_HYBLA=m
-CONFIG_TCP_CONG_SCALABLE=m
-CONFIG_TCP_CONG_LP=m
-CONFIG_TCP_CONG_VENO=m
-CONFIG_TCP_CONG_YEAH=m
-CONFIG_TCP_CONG_ILLINOIS=m
-CONFIG_IPV6_ROUTER_PREF=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_MIP6=m
-CONFIG_INET6_XFRM_MODE_TRANSPORT=m
-CONFIG_INET6_XFRM_MODE_TUNNEL=m
-CONFIG_INET6_XFRM_MODE_BEET=m
-CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
-CONFIG_IPV6_VTI=m
-CONFIG_IPV6_SIT=m
-CONFIG_IPV6_GRE=m
-CONFIG_IPV6_MULTIPLE_TABLES=y
-CONFIG_IPV6_SUBTREES=y
-CONFIG_NETFILTER=y
-CONFIG_NF_CONNTRACK=m
-CONFIG_NF_CONNTRACK_SECMARK=y
-CONFIG_NF_CONNTRACK_EVENTS=y
-CONFIG_NF_CONNTRACK_TIMEOUT=y
-CONFIG_NF_CONNTRACK_TIMESTAMP=y
-CONFIG_NF_CONNTRACK_AMANDA=m
-CONFIG_NF_CONNTRACK_FTP=m
-CONFIG_NF_CONNTRACK_H323=m
-CONFIG_NF_CONNTRACK_IRC=m
-CONFIG_NF_CONNTRACK_NETBIOS_NS=m
-CONFIG_NF_CONNTRACK_SNMP=m
-CONFIG_NF_CONNTRACK_PPTP=m
-CONFIG_NF_CONNTRACK_SANE=m
-CONFIG_NF_CONNTRACK_SIP=m
-CONFIG_NF_CONNTRACK_TFTP=m
-CONFIG_NF_CT_NETLINK=m
-CONFIG_NF_CT_NETLINK_TIMEOUT=m
-CONFIG_NF_TABLES=m
-CONFIG_NFT_EXTHDR=m
-CONFIG_NFT_META=m
-CONFIG_NFT_CT=m
-CONFIG_NFT_COUNTER=m
-CONFIG_NFT_LOG=m
-CONFIG_NFT_LIMIT=m
-CONFIG_NFT_NAT=m
-CONFIG_NFT_COMPAT=m
-CONFIG_NFT_HASH=m
-CONFIG_NETFILTER_XT_SET=m
-CONFIG_NETFILTER_XT_TARGET_AUDIT=m
-CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CT=m
-CONFIG_NETFILTER_XT_TARGET_DSCP=m
-CONFIG_NETFILTER_XT_TARGET_HMARK=m
-CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
-CONFIG_NETFILTER_XT_TARGET_LOG=m
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-CONFIG_NETFILTER_XT_TARGET_NFLOG=m
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_TEE=m
-CONFIG_NETFILTER_XT_TARGET_TPROXY=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
-CONFIG_NETFILTER_XT_MATCH_BPF=m
-CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
-CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
-CONFIG_NETFILTER_XT_MATCH_CPU=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
-CONFIG_NETFILTER_XT_MATCH_DSCP=m
-CONFIG_NETFILTER_XT_MATCH_ESP=m
-CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
-CONFIG_NETFILTER_XT_MATCH_HELPER=m
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_IPVS=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_NFACCT=m
-CONFIG_NETFILTER_XT_MATCH_OSF=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-CONFIG_NETFILTER_XT_MATCH_POLICY=m
-CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-CONFIG_NETFILTER_XT_MATCH_STATE=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-CONFIG_IP_SET=m
-CONFIG_IP_SET_BITMAP_IP=m
-CONFIG_IP_SET_BITMAP_IPMAC=m
-CONFIG_IP_SET_BITMAP_PORT=m
-CONFIG_IP_SET_HASH_IP=m
-CONFIG_IP_SET_HASH_IPPORT=m
-CONFIG_IP_SET_HASH_IPPORTIP=m
-CONFIG_IP_SET_HASH_IPPORTNET=m
-CONFIG_IP_SET_HASH_NETPORTNET=m
-CONFIG_IP_SET_HASH_NET=m
-CONFIG_IP_SET_HASH_NETNET=m
-CONFIG_IP_SET_HASH_NETPORT=m
-CONFIG_IP_SET_HASH_NETIFACE=m
-CONFIG_IP_SET_LIST_SET=m
-CONFIG_IP_VS=m
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-CONFIG_IP_VS_FTP=m
-CONFIG_IP_VS_PE_SIP=m
-CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_NF_TABLES_IPV4=m
-CONFIG_NFT_CHAIN_ROUTE_IPV4=m
-CONFIG_NF_TABLES_ARP=m
-CONFIG_NFT_CHAIN_NAT_IPV4=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_RPFILTER=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_SECURITY=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_NF_TABLES_IPV6=m
-CONFIG_NFT_CHAIN_ROUTE_IPV6=m
-CONFIG_NFT_CHAIN_NAT_IPV6=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_AH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_MH=m
-CONFIG_IP6_NF_MATCH_RPFILTER=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP6_NF_SECURITY=m
-CONFIG_IP6_NF_NAT=m
-CONFIG_IP6_NF_TARGET_MASQUERADE=m
-CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
-CONFIG_RDS=m
-CONFIG_RDS_RDMA=m
-CONFIG_RDS_TCP=m
-CONFIG_L2TP=m
-CONFIG_L2TP_DEBUGFS=m
-CONFIG_L2TP_V3=y
-CONFIG_L2TP_IP=m
-CONFIG_L2TP_ETH=m
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_MULTIQ=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFB=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_DRR=m
-CONFIG_NET_SCH_MQPRIO=m
-CONFIG_NET_SCH_CHOKE=m
-CONFIG_NET_SCH_QFQ=m
-CONFIG_NET_SCH_CODEL=m
-CONFIG_NET_SCH_FQ_CODEL=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_SCH_PLUG=m
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_CLS_U32_PERF=y
-CONFIG_CLS_U32_MARK=y
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_FLOW=m
-CONFIG_NET_CLS_CGROUP=y
-CONFIG_NET_CLS_BPF=m
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=m
-CONFIG_NET_ACT_GACT=m
-CONFIG_GACT_PROB=y
-CONFIG_NET_ACT_MIRRED=m
-CONFIG_NET_ACT_IPT=m
-CONFIG_NET_ACT_NAT=m
-CONFIG_NET_ACT_PEDIT=m
-CONFIG_NET_ACT_SIMP=m
-CONFIG_NET_ACT_SKBEDIT=m
-CONFIG_NET_ACT_CSUM=m
-CONFIG_DNS_RESOLVER=y
-CONFIG_NETLINK_DIAG=m
-CONFIG_CGROUP_NET_PRIO=y
-CONFIG_BPF_JIT=y
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-CONFIG_DEVTMPFS=y
-CONFIG_DMA_CMA=y
-CONFIG_CMA_SIZE_MBYTES=0
-CONFIG_CONNECTOR=y
-CONFIG_ZRAM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_DRBD=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_ENCLOSURE_SERVICES=m
-CONFIG_GENWQE=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_ENCLOSURE=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=m
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_SCSI_SRP_ATTRS=m
-CONFIG_ISCSI_TCP=m
-CONFIG_SCSI_DEBUG=m
-CONFIG_ZFCP=y
-CONFIG_SCSI_VIRTIO=m
-CONFIG_SCSI_DH=y
-CONFIG_SCSI_DH_RDAC=m
-CONFIG_SCSI_DH_HP_SW=m
-CONFIG_SCSI_DH_EMC=m
-CONFIG_SCSI_DH_ALUA=m
-CONFIG_SCSI_OSD_INITIATOR=m
-CONFIG_SCSI_OSD_ULD=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_MULTIPATH=m
-CONFIG_MD_FAULTY=m
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_THIN_PROVISIONING=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_LOG_USERSPACE=m
-CONFIG_DM_RAID=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_QL=m
-CONFIG_DM_MULTIPATH_ST=m
-CONFIG_DM_DELAY=m
-CONFIG_DM_UEVENT=y
-CONFIG_DM_FLAKEY=m
-CONFIG_DM_VERITY=m
-CONFIG_DM_SWITCH=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_EQUALIZER=m
-CONFIG_IFB=m
-CONFIG_MACVLAN=m
-CONFIG_MACVTAP=m
-CONFIG_VXLAN=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_VIRTIO_NET=m
-CONFIG_NLMON=m
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_VENDOR_CHELSIO is not set
-# CONFIG_NET_VENDOR_INTEL is not set
-# CONFIG_NET_VENDOR_MARVELL is not set
-CONFIG_MLX4_EN=m
-CONFIG_MLX5_CORE=m
-CONFIG_MLX5_CORE_EN=y
-# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPTP=m
-CONFIG_PPPOL2TP=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_HW_RANDOM_VIRTIO=m
-CONFIG_RAW_DRIVER=m
-CONFIG_HANGCHECK_TIMER=m
-CONFIG_TN3270_FS=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_SOFT_WATCHDOG=m
-CONFIG_DIAG288_WATCHDOG=m
-# CONFIG_HID is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_ACCESS=m
-CONFIG_MLX4_INFINIBAND=m
-CONFIG_MLX5_INFINIBAND=m
-CONFIG_VFIO=m
-CONFIG_VFIO_PCI=m
-CONFIG_VIRTIO_BALLOON=m
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
-CONFIG_JBD2_DEBUG=y
-CONFIG_JFS_FS=m
-CONFIG_JFS_POSIX_ACL=y
-CONFIG_JFS_SECURITY=y
-CONFIG_JFS_STATISTICS=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_XFS_RT=y
-CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
-CONFIG_BTRFS_FS=y
-CONFIG_BTRFS_FS_POSIX_ACL=y
-CONFIG_NILFS2_FS=m
-CONFIG_FS_DAX=y
-CONFIG_EXPORTFS_BLOCK_OPS=y
-CONFIG_FANOTIFY=y
-CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
-CONFIG_QUOTA_NETLINK_INTERFACE=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=y
-CONFIG_CUSE=m
-CONFIG_OVERLAY_FS=m
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
-CONFIG_FSCACHE=m
-CONFIG_CACHEFILES=m
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=m
-CONFIG_ECRYPT_FS=m
-CONFIG_CRAMFS=m
-CONFIG_SQUASHFS=m
-CONFIG_SQUASHFS_XATTR=y
-CONFIG_SQUASHFS_LZO=y
-CONFIG_SQUASHFS_XZ=y
-CONFIG_ROMFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=m
-CONFIG_NFS_SWAP=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_V4_SECURITY_LABEL=y
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_UPCALL=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_DEBUG is not set
-CONFIG_CIFS_DFS_UPCALL=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_INFO_DWARF4=y
-CONFIG_GDB_SCRIPTS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_RCU_TORTURE_TEST=m
-CONFIG_RCU_CPU_STALL_TIMEOUT=60
-CONFIG_LATENCYTOP=y
-CONFIG_SCHED_TRACER=y
-CONFIG_FTRACE_SYSCALLS=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_FUNCTION_PROFILER=y
-CONFIG_HIST_TRIGGERS=y
-CONFIG_LKDTM=m
-CONFIG_PERCPU_TEST=m
-CONFIG_ATOMIC64_SELFTEST=y
-CONFIG_TEST_BPF=m
-CONFIG_BUG_ON_DATA_CORRUPTION=y
-CONFIG_S390_PTDUMP=y
-CONFIG_PERSISTENT_KEYRINGS=y
-CONFIG_BIG_KEYS=y
-CONFIG_ENCRYPTED_KEYS=m
-CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
-CONFIG_SECURITY_SELINUX=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM=y
-CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
-CONFIG_SECURITY_SELINUX_DISABLE=y
-CONFIG_INTEGRITY_SIGNATURE=y
-CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
-CONFIG_IMA=y
-CONFIG_IMA_WRITE_POLICY=y
-CONFIG_IMA_APPRAISE=y
-CONFIG_CRYPTO_DH=m
-CONFIG_CRYPTO_ECDH=m
-CONFIG_CRYPTO_USER=m
-# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
-CONFIG_CRYPTO_PCRYPT=m
-CONFIG_CRYPTO_CRYPTD=m
-CONFIG_CRYPTO_MCRYPTD=m
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_CHACHA20POLY1305=m
-CONFIG_CRYPTO_LRW=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_KEYWRAP=m
-CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_VMAC=m
-CONFIG_CRYPTO_CRC32=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_SHA3=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_AES_TI=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAMELLIA=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_FCRYPT=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_842=m
-CONFIG_CRYPTO_LZ4=m
-CONFIG_CRYPTO_LZ4HC=m
-CONFIG_CRYPTO_ANSI_CPRNG=m
-CONFIG_CRYPTO_USER_API_HASH=m
-CONFIG_CRYPTO_USER_API_SKCIPHER=m
-CONFIG_CRYPTO_USER_API_RNG=m
-CONFIG_CRYPTO_USER_API_AEAD=m
-CONFIG_ZCRYPT=m
-CONFIG_PKEY=m
-CONFIG_CRYPTO_PAES_S390=m
-CONFIG_CRYPTO_SHA1_S390=m
-CONFIG_CRYPTO_SHA256_S390=m
-CONFIG_CRYPTO_SHA512_S390=m
-CONFIG_CRYPTO_DES_S390=m
-CONFIG_CRYPTO_AES_S390=m
-CONFIG_CRYPTO_GHASH_S390=m
-CONFIG_CRYPTO_CRC32_S390=y
-CONFIG_CRC7=m
-CONFIG_CRC8=m
-CONFIG_CORDIC=m
-CONFIG_CMM=m
-CONFIG_APPLDATA_BASE=y
-CONFIG_KVM=m
-CONFIG_KVM_S390_UCONTROL=y
-CONFIG_VHOST_NET=m
index 20ed149..c105bcc 100644 (file)
@@ -25,13 +25,13 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -45,6 +45,8 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_SHA256=y
 CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_BLK_WBT=y
@@ -62,6 +64,7 @@ CONFIG_TUNE_ZEC12=y
 CONFIG_NR_CPUS=512
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -301,7 +304,6 @@ CONFIG_IP6_NF_SECURITY=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_NF_TABLES_BRIDGE=m
-CONFIG_NET_SCTPPROBE=m
 CONFIG_RDS=m
 CONFIG_RDS_RDMA=m
 CONFIG_RDS_TCP=m
@@ -359,11 +361,11 @@ CONFIG_NET_ACT_SIMP=m
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_NET_ACT_CSUM=m
 CONFIG_DNS_RESOLVER=y
+CONFIG_OPENVSWITCH=m
 CONFIG_NETLINK_DIAG=m
 CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
 CONFIG_DEVTMPFS=y
 CONFIG_DMA_CMA=y
 CONFIG_CMA_SIZE_MBYTES=0
@@ -375,8 +377,9 @@ CONFIG_BLK_DEV_DRBD=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_DAX=y
 CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
+CONFIG_BLK_DEV_NVME=m
 CONFIG_ENCLOSURE_SERVICES=m
 CONFIG_GENWQE=m
 CONFIG_RAID_ATTRS=m
@@ -455,6 +458,7 @@ CONFIG_PPTP=m
 CONFIG_PPPOL2TP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
+CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
@@ -468,6 +472,9 @@ CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
 CONFIG_SOFT_WATCHDOG=m
 CONFIG_DIAG288_WATCHDOG=m
+CONFIG_DRM=y
+CONFIG_DRM_VIRTIO_GPU=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
 # CONFIG_HID is not set
 # CONFIG_USB_SUPPORT is not set
 CONFIG_INFINIBAND=m
@@ -476,7 +483,9 @@ CONFIG_MLX4_INFINIBAND=m
 CONFIG_MLX5_INFINIBAND=m
 CONFIG_VFIO=m
 CONFIG_VFIO_PCI=m
+CONFIG_VIRTIO_PCI=m
 CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
@@ -507,7 +516,6 @@ CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
 CONFIG_OVERLAY_FS=m
-CONFIG_OVERLAY_FS_REDIRECT_DIR=y
 CONFIG_FSCACHE=m
 CONFIG_CACHEFILES=m
 CONFIG_ISO9660_FS=y
@@ -592,8 +600,10 @@ CONFIG_SECURITY_SELINUX_DISABLE=y
 CONFIG_INTEGRITY_SIGNATURE=y
 CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
 CONFIG_IMA=y
+CONFIG_IMA_DEFAULT_HASH_SHA256=y
 CONFIG_IMA_WRITE_POLICY=y
 CONFIG_IMA_APPRAISE=y
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_DH=m
 CONFIG_CRYPTO_ECDH=m
 CONFIG_CRYPTO_USER=m
index 46a3178..f40600e 100644 (file)
@@ -8,6 +8,7 @@ CONFIG_TASKSTATS=y
 CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_CPU_ISOLATION is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
@@ -23,12 +24,12 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
-CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 # CONFIG_SYSFS_SYSCALL is not set
+CONFIG_CHECKPOINT_RESTORE=y
 CONFIG_BPF_SYSCALL=y
 CONFIG_USERFAULTFD=y
 # CONFIG_COMPAT_BRK is not set
@@ -47,6 +48,7 @@ CONFIG_LIVEPATCH=y
 CONFIG_NR_CPUS=256
 CONFIG_NUMA=y
 CONFIG_HZ_100=y
+CONFIG_KEXEC_FILE=y
 CONFIG_MEMORY_HOTPLUG=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_KSM=y
@@ -129,10 +131,13 @@ CONFIG_EQUALIZER=m
 CONFIG_TUN=m
 CONFIG_VIRTIO_NET=y
 # CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
 # CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
 # CONFIG_NET_VENDOR_SYNOPSYS is not set
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
+# CONFIG_VT is not set
 CONFIG_DEVKMEM=y
 CONFIG_RAW_DRIVER=m
 CONFIG_VIRTIO_BALLOON=y
@@ -177,13 +182,15 @@ CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
 CONFIG_STACK_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_FUNCTION_PROFILER=y
-CONFIG_KPROBES_SANITY_TEST=y
+# CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_S390_PTDUMP=y
 CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CFB=m
 CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -213,6 +220,8 @@ CONFIG_CRYPTO_KHAZAD=m
 CONFIG_CRYPTO_SALSA20=m
 CONFIG_CRYPTO_SEED=m
 CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_SM4=m
+CONFIG_CRYPTO_SPECK=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_TWOFISH=m
 CONFIG_CRYPTO_DEFLATE=m
index 43bbe63..06b513d 100644 (file)
@@ -320,7 +320,7 @@ static void hypfs_kill_super(struct super_block *sb)
 
        if (sb->s_root)
                hypfs_delete_tree(sb->s_root);
-       if (sb_info->update_file)
+       if (sb_info && sb_info->update_file)
                hypfs_remove(sb_info->update_file);
        kfree(sb->s_fs_info);
        sb->s_fs_info = NULL;
index 1d708a4..825dd0f 100644 (file)
 static inline void crash_setup_regs(struct pt_regs *newregs,
                                        struct pt_regs *oldregs) { }
 
+struct kimage;
+struct s390_load_data {
+       /* Pointer to the kernel buffer. Used to register cmdline etc.. */
+       void *kernel_buf;
+
+       /* Total size of loaded segments in memory. Used as an offset. */
+       size_t memsz;
+
+       /* Load address of initrd. Used to register INITRD_START in kernel. */
+       unsigned long initrd_load_addr;
+};
+
+int kexec_file_add_purgatory(struct kimage *image,
+                            struct s390_load_data *data);
+int kexec_file_add_initrd(struct kimage *image,
+                         struct s390_load_data *data,
+                         char *initrd, unsigned long initrd_len);
+int *kexec_file_update_kernel(struct kimage *iamge,
+                             struct s390_load_data *data);
+
+extern const struct kexec_file_ops s390_kexec_image_ops;
+extern const struct kexec_file_ops s390_kexec_elf_ops;
+
 #endif /*_S390_KEXEC_H */
diff --git a/arch/s390/include/asm/purgatory.h b/arch/s390/include/asm/purgatory.h
new file mode 100644 (file)
index 0000000..e297bcf
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#ifndef _S390_PURGATORY_H_
+#define _S390_PURGATORY_H_
+#ifndef __ASSEMBLY__
+
+#include <linux/purgatory.h>
+
+int verify_sha256_digest(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _S390_PURGATORY_H_ */
index 124154f..9c30ebe 100644 (file)
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  *  S390 version
- *    Copyright IBM Corp. 1999, 2010
+ *    Copyright IBM Corp. 1999, 2017
  */
 #ifndef _ASM_S390_SETUP_H
 #define _ASM_S390_SETUP_H
 #define LPP_MAGIC              _BITUL(31)
 #define LPP_PID_MASK           _AC(0xffffffff, UL)
 
+/* Offsets to entry points in kernel/head.S  */
+
+#define STARTUP_NORMAL_OFFSET  0x10000
+#define STARTUP_KDUMP_OFFSET   0x10010
+
+/* Offsets to parameters in kernel/head.S  */
+
+#define IPL_DEVICE_OFFSET      0x10400
+#define INITRD_START_OFFSET    0x10408
+#define INITRD_SIZE_OFFSET     0x10410
+#define OLDMEM_BASE_OFFSET     0x10418
+#define OLDMEM_SIZE_OFFSET     0x10420
+#define COMMAND_LINE_OFFSET    0x10480
+
 #ifndef __ASSEMBLY__
 
 #include <asm/lowcore.h>
 #include <asm/types.h>
 
-#define IPL_DEVICE        (*(unsigned long *)  (0x10400))
-#define INITRD_START      (*(unsigned long *)  (0x10408))
-#define INITRD_SIZE       (*(unsigned long *)  (0x10410))
-#define OLDMEM_BASE      (*(unsigned long *)  (0x10418))
-#define OLDMEM_SIZE      (*(unsigned long *)  (0x10420))
-#define COMMAND_LINE      ((char *)            (0x10480))
+#define IPL_DEVICE     (*(unsigned long *)  (IPL_DEVICE_OFFSET))
+#define INITRD_START   (*(unsigned long *)  (INITRD_START_OFFSET))
+#define INITRD_SIZE    (*(unsigned long *)  (INITRD_SIZE_OFFSET))
+#define OLDMEM_BASE    (*(unsigned long *)  (OLDMEM_BASE_OFFSET))
+#define OLDMEM_SIZE    (*(unsigned long *)  (OLDMEM_SIZE_OFFSET))
+#define COMMAND_LINE   ((char *)            (COMMAND_LINE_OFFSET))
 
 extern int memory_end_set;
 extern unsigned long memory_end;
@@ -121,12 +135,12 @@ extern void (*_machine_power_off)(void);
 
 #else /* __ASSEMBLY__ */
 
-#define IPL_DEVICE        0x10400
-#define INITRD_START      0x10408
-#define INITRD_SIZE       0x10410
-#define OLDMEM_BASE      0x10418
-#define OLDMEM_SIZE      0x10420
-#define COMMAND_LINE      0x10480
+#define IPL_DEVICE     (IPL_DEVICE_OFFSET)
+#define INITRD_START   (INITRD_START_OFFSET)
+#define INITRD_SIZE    (INITRD_SIZE_OFFSET)
+#define OLDMEM_BASE    (OLDMEM_BASE_OFFSET)
+#define OLDMEM_SIZE    (OLDMEM_SIZE_OFFSET)
+#define COMMAND_LINE   (COMMAND_LINE_OFFSET)
 
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_S390_SETUP_H */
index c57f9d2..9a14a61 100644 (file)
@@ -97,22 +97,31 @@ typedef unsigned long sigset_t;
 #include <asm-generic/signal-defs.h>
 
 #ifndef __KERNEL__
-/* Here we must cater to libcs that poke about in kernel headers.  */
 
+/*
+ * There are two system calls in regard to sigaction, sys_rt_sigaction
+ * and sys_sigaction. Internally the kernel uses the struct old_sigaction
+ * for the older sys_sigaction system call, and the kernel version of the
+ * struct sigaction for the newer sys_rt_sigaction.
+ *
+ * The uapi definition for struct sigaction has made a strange distinction
+ * between 31-bit and 64-bit in the past. For 64-bit the uapi structure
+ * looks like the kernel struct sigaction, but for 31-bit it used to
+ * look like the kernel struct old_sigaction. That practically made the
+ * structure unusable for either system call. To get around this problem
+ * the glibc always had its own definitions for the sigaction structures.
+ *
+ * The current struct sigaction uapi definition below is suitable for the
+ * sys_rt_sigaction system call only.
+ */
 struct sigaction {
         union {
           __sighandler_t _sa_handler;
           void (*_sa_sigaction)(int, struct siginfo *, void *);
         } _u;
-#ifndef __s390x__ /* lovely */
-        sigset_t sa_mask;
-        unsigned long sa_flags;
-        void (*sa_restorer)(void);
-#else  /* __s390x__ */
         unsigned long sa_flags;
         void (*sa_restorer)(void);
        sigset_t sa_mask;
-#endif /* __s390x__ */
 };
 
 #define sa_handler      _u._sa_handler
index b06a6f7..84ea622 100644 (file)
@@ -82,6 +82,9 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_UPROBES)          += uprobes.o
 
+obj-$(CONFIG_KEXEC_FILE)       += machine_kexec_file.o kexec_image.o
+obj-$(CONFIG_KEXEC_FILE)       += kexec_elf.o
+
 obj-$(CONFIG_PERF_EVENTS)      += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
 obj-$(CONFIG_PERF_EVENTS)      += perf_cpum_cf_events.o perf_regs.o
 
index cfe2c45..eb2a5c0 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kbuild.h>
 #include <linux/kvm_host.h>
 #include <linux/sched.h>
+#include <linux/purgatory.h>
 #include <asm/idle.h>
 #include <asm/vdso.h>
 #include <asm/pgtable.h>
@@ -204,5 +205,9 @@ int main(void)
        OFFSET(__GMAP_ASCE, gmap, asce);
        OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c);
        OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20);
+       /* kexec_sha_region */
+       OFFSET(__KEXEC_SHA_REGION_START, kexec_sha_region, start);
+       OFFSET(__KEXEC_SHA_REGION_LEN, kexec_sha_region, len);
+       DEFINE(__KEXEC_SHA_REGION_SIZE, sizeof(struct kexec_sha_region));
        return 0;
 }
index 11e9d8b..607c5e9 100644 (file)
@@ -182,3 +182,4 @@ COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int,
 COMPAT_SYSCALL_WRAP2(s390_guarded_storage, int, command, struct gs_cb *, gs_cb);
 COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags, unsigned, mask, struct statx __user *, buffer);
 COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags);
+COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags)
diff --git a/arch/s390/kernel/kexec_elf.c b/arch/s390/kernel/kexec_elf.c
new file mode 100644 (file)
index 0000000..5a286b0
--- /dev/null
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ELF loader for kexec_file_load system call.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+static int kexec_file_add_elf_kernel(struct kimage *image,
+                                    struct s390_load_data *data,
+                                    char *kernel, unsigned long kernel_len)
+{
+       struct kexec_buf buf;
+       const Elf_Ehdr *ehdr;
+       const Elf_Phdr *phdr;
+       int i, ret;
+
+       ehdr = (Elf_Ehdr *)kernel;
+       buf.image = image;
+
+       phdr = (void *)ehdr + ehdr->e_phoff;
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               if (phdr->p_type != PT_LOAD)
+                       continue;
+
+               buf.buffer = kernel + phdr->p_offset;
+               buf.bufsz = phdr->p_filesz;
+
+               buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
+               buf.memsz = phdr->p_memsz;
+
+               if (phdr->p_paddr == 0) {
+                       data->kernel_buf = buf.buffer;
+                       data->memsz += STARTUP_NORMAL_OFFSET;
+
+                       buf.buffer += STARTUP_NORMAL_OFFSET;
+                       buf.bufsz -= STARTUP_NORMAL_OFFSET;
+
+                       buf.mem += STARTUP_NORMAL_OFFSET;
+                       buf.memsz -= STARTUP_NORMAL_OFFSET;
+               }
+
+               if (image->type == KEXEC_TYPE_CRASH)
+                       buf.mem += crashk_res.start;
+
+               ret = kexec_add_buffer(&buf);
+               if (ret)
+                       return ret;
+
+               data->memsz += buf.memsz;
+       }
+
+       return 0;
+}
+
+static void *s390_elf_load(struct kimage *image,
+                          char *kernel, unsigned long kernel_len,
+                          char *initrd, unsigned long initrd_len,
+                          char *cmdline, unsigned long cmdline_len)
+{
+       struct s390_load_data data = {0};
+       const Elf_Ehdr *ehdr;
+       const Elf_Phdr *phdr;
+       size_t size;
+       int i, ret;
+
+       /* image->fobs->probe already checked for valid ELF magic number. */
+       ehdr = (Elf_Ehdr *)kernel;
+
+       if (ehdr->e_type != ET_EXEC ||
+           ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
+           !elf_check_arch(ehdr))
+               return ERR_PTR(-EINVAL);
+
+       if (!ehdr->e_phnum || ehdr->e_phentsize != sizeof(Elf_Phdr))
+               return ERR_PTR(-EINVAL);
+
+       size = ehdr->e_ehsize + ehdr->e_phoff;
+       size += ehdr->e_phentsize * ehdr->e_phnum;
+       if (size > kernel_len)
+               return ERR_PTR(-EINVAL);
+
+       phdr = (void *)ehdr + ehdr->e_phoff;
+       size = ALIGN(size, phdr->p_align);
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               if (phdr->p_type == PT_INTERP)
+                       return ERR_PTR(-EINVAL);
+
+               if (phdr->p_offset > kernel_len)
+                       return ERR_PTR(-EINVAL);
+
+               size += ALIGN(phdr->p_filesz, phdr->p_align);
+       }
+
+       if (size > kernel_len)
+               return ERR_PTR(-EINVAL);
+
+       ret = kexec_file_add_elf_kernel(image, &data, kernel, kernel_len);
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (!data.memsz)
+               return ERR_PTR(-EINVAL);
+
+       if (initrd) {
+               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       ret = kexec_file_add_purgatory(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return kexec_file_update_kernel(image, &data);
+}
+
+static int s390_elf_probe(const char *buf, unsigned long len)
+{
+       const Elf_Ehdr *ehdr;
+
+       if (len < sizeof(Elf_Ehdr))
+               return -ENOEXEC;
+
+       ehdr = (Elf_Ehdr *)buf;
+
+       /* Only check the ELF magic number here and do proper validity check
+        * in the loader. Any check here that fails would send the erroneous
+        * ELF file to the image loader that does not care what it gets.
+        * (Most likely) causing behavior not intended by the user.
+        */
+       if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
+               return -ENOEXEC;
+
+       return 0;
+}
+
+const struct kexec_file_ops s390_kexec_elf_ops = {
+       .probe = s390_elf_probe,
+       .load = s390_elf_load,
+};
diff --git a/arch/s390/kernel/kexec_image.c b/arch/s390/kernel/kexec_image.c
new file mode 100644 (file)
index 0000000..3800852
--- /dev/null
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Image loader for kexec_file_load system call.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+static int kexec_file_add_image_kernel(struct kimage *image,
+                                      struct s390_load_data *data,
+                                      char *kernel, unsigned long kernel_len)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       buf.buffer = kernel + STARTUP_NORMAL_OFFSET;
+       buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET;
+
+       buf.mem = STARTUP_NORMAL_OFFSET;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+       buf.memsz = buf.bufsz;
+
+       ret = kexec_add_buffer(&buf);
+
+       data->kernel_buf = kernel;
+       data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET;
+
+       return ret;
+}
+
+static void *s390_image_load(struct kimage *image,
+                            char *kernel, unsigned long kernel_len,
+                            char *initrd, unsigned long initrd_len,
+                            char *cmdline, unsigned long cmdline_len)
+{
+       struct s390_load_data data = {0};
+       int ret;
+
+       ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len);
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (initrd) {
+               ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       ret = kexec_file_add_purgatory(image, &data);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return kexec_file_update_kernel(image, &data);
+}
+
+static int s390_image_probe(const char *buf, unsigned long len)
+{
+       /* Can't reliably tell if an image is valid.  Therefore give the
+        * user whatever he wants.
+        */
+       return 0;
+}
+
+const struct kexec_file_ops s390_kexec_image_ops = {
+       .probe = s390_image_probe,
+       .load = s390_image_load,
+};
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
new file mode 100644 (file)
index 0000000..f413f57
--- /dev/null
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * s390 code for kexec_file_load system call
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/elf.h>
+#include <linux/kexec.h>
+#include <asm/setup.h>
+
+const struct kexec_file_ops * const kexec_file_loaders[] = {
+       &s390_kexec_elf_ops,
+       &s390_kexec_image_ops,
+       NULL,
+};
+
+int *kexec_file_update_kernel(struct kimage *image,
+                             struct s390_load_data *data)
+{
+       unsigned long *loc;
+
+       if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE)
+               return ERR_PTR(-EINVAL);
+
+       if (image->cmdline_buf_len)
+               memcpy(data->kernel_buf + COMMAND_LINE_OFFSET,
+                      image->cmdline_buf, image->cmdline_buf_len);
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               loc = (unsigned long *)(data->kernel_buf + OLDMEM_BASE_OFFSET);
+               *loc = crashk_res.start;
+
+               loc = (unsigned long *)(data->kernel_buf + OLDMEM_SIZE_OFFSET);
+               *loc = crashk_res.end - crashk_res.start + 1;
+       }
+
+       if (image->initrd_buf) {
+               loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET);
+               *loc = data->initrd_load_addr;
+
+               loc = (unsigned long *)(data->kernel_buf + INITRD_SIZE_OFFSET);
+               *loc = image->initrd_buf_len;
+       }
+
+       return NULL;
+}
+
+static int kexec_file_update_purgatory(struct kimage *image)
+{
+       u64 entry, type;
+       int ret;
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               entry = STARTUP_KDUMP_OFFSET;
+               type = KEXEC_TYPE_CRASH;
+       } else {
+               entry = STARTUP_NORMAL_OFFSET;
+               type = KEXEC_TYPE_DEFAULT;
+       }
+
+       ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry,
+                                            sizeof(entry), false);
+       if (ret)
+               return ret;
+
+       ret = kexec_purgatory_get_set_symbol(image, "kernel_type", &type,
+                                            sizeof(type), false);
+       if (ret)
+               return ret;
+
+       if (image->type == KEXEC_TYPE_CRASH) {
+               u64 crash_size;
+
+               ret = kexec_purgatory_get_set_symbol(image, "crash_start",
+                                                    &crashk_res.start,
+                                                    sizeof(crashk_res.start),
+                                                    false);
+               if (ret)
+                       return ret;
+
+               crash_size = crashk_res.end - crashk_res.start + 1;
+               ret = kexec_purgatory_get_set_symbol(image, "crash_size",
+                                                    &crash_size,
+                                                    sizeof(crash_size),
+                                                    false);
+       }
+       return ret;
+}
+
+int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       data->memsz = ALIGN(data->memsz, PAGE_SIZE);
+       buf.mem = data->memsz;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+
+       ret = kexec_load_purgatory(image, &buf);
+       if (ret)
+               return ret;
+
+       ret = kexec_file_update_purgatory(image);
+       return ret;
+}
+
+int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data,
+                         char *initrd, unsigned long initrd_len)
+{
+       struct kexec_buf buf;
+       int ret;
+
+       buf.image = image;
+
+       buf.buffer = initrd;
+       buf.bufsz = initrd_len;
+
+       data->memsz = ALIGN(data->memsz, PAGE_SIZE);
+       buf.mem = data->memsz;
+       if (image->type == KEXEC_TYPE_CRASH)
+               buf.mem += crashk_res.start;
+       buf.memsz = buf.bufsz;
+
+       data->initrd_load_addr = buf.mem;
+       data->memsz += buf.memsz;
+
+       ret = kexec_add_buffer(&buf);
+       return ret;
+}
+
+/*
+ * The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole
+ * and provide kbuf->mem by hand.
+ */
+int arch_kexec_walk_mem(struct kexec_buf *kbuf,
+                       int (*func)(struct resource *, void *))
+{
+       return 1;
+}
+
+int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
+                                    Elf_Shdr *section,
+                                    const Elf_Shdr *relsec,
+                                    const Elf_Shdr *symtab)
+{
+       Elf_Rela *relas;
+       int i;
+
+       relas = (void *)pi->ehdr + relsec->sh_offset;
+
+       for (i = 0; i < relsec->sh_size / sizeof(*relas); i++) {
+               const Elf_Sym *sym;     /* symbol to relocate */
+               unsigned long addr;     /* final location after relocation */
+               unsigned long val;      /* relocated symbol value */
+               void *loc;              /* tmp location to modify */
+
+               sym = (void *)pi->ehdr + symtab->sh_offset;
+               sym += ELF64_R_SYM(relas[i].r_info);
+
+               if (sym->st_shndx == SHN_UNDEF)
+                       return -ENOEXEC;
+
+               if (sym->st_shndx == SHN_COMMON)
+                       return -ENOEXEC;
+
+               if (sym->st_shndx >= pi->ehdr->e_shnum &&
+                   sym->st_shndx != SHN_ABS)
+                       return -ENOEXEC;
+
+               loc = pi->purgatory_buf;
+               loc += section->sh_offset;
+               loc += relas[i].r_offset;
+
+               val = sym->st_value;
+               if (sym->st_shndx != SHN_ABS)
+                       val += pi->sechdrs[sym->st_shndx].sh_addr;
+               val += relas[i].r_addend;
+
+               addr = section->sh_addr + relas[i].r_offset;
+
+               switch (ELF64_R_TYPE(relas[i].r_info)) {
+               case R_390_8:           /* Direct 8 bit.   */
+                       *(u8 *)loc = val;
+                       break;
+               case R_390_12:          /* Direct 12 bit.  */
+                       *(u16 *)loc &= 0xf000;
+                       *(u16 *)loc |= val & 0xfff;
+                       break;
+               case R_390_16:          /* Direct 16 bit.  */
+                       *(u16 *)loc = val;
+                       break;
+               case R_390_20:          /* Direct 20 bit.  */
+                       *(u32 *)loc &= 0xf00000ff;
+                       *(u32 *)loc |= (val & 0xfff) << 16;     /* DL */
+                       *(u32 *)loc |= (val & 0xff000) >> 4;    /* DH */
+                       break;
+               case R_390_32:          /* Direct 32 bit.  */
+                       *(u32 *)loc = val;
+                       break;
+               case R_390_64:          /* Direct 64 bit.  */
+                       *(u64 *)loc = val;
+                       break;
+               case R_390_PC16:        /* PC relative 16 bit.  */
+                       *(u16 *)loc = (val - addr);
+                       break;
+               case R_390_PC16DBL:     /* PC relative 16 bit shifted by 1.  */
+                       *(u16 *)loc = (val - addr) >> 1;
+                       break;
+               case R_390_PC32DBL:     /* PC relative 32 bit shifted by 1.  */
+                       *(u32 *)loc = (val - addr) >> 1;
+                       break;
+               case R_390_PC32:        /* PC relative 32 bit.  */
+                       *(u32 *)loc = (val - addr);
+                       break;
+               case R_390_PC64:        /* PC relative 64 bit.  */
+                       *(u64 *)loc = (val - addr);
+                       break;
+               default:
+                       break;
+               }
+       }
+       return 0;
+}
+
+int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
+                                 unsigned long buf_len)
+{
+       /* A kernel must be at least large enough to contain head.S. During
+        * load memory in head.S will be accessed, e.g. to register the next
+        * command line. If the next kernel were smaller the current kernel
+        * will panic at load.
+        *
+        * 0x11000 = sizeof(head.S)
+        */
+       if (buf_len < 0x11000)
+               return -ENOEXEC;
+
+       return kexec_image_probe_default(image, buf, buf_len);
+}
index f236ce8..46d49a1 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/cpu.h>
 #include <asm/nospec-branch.h>
 
 static int __init nobp_setup_early(char *str)
index c5bc3f2..5ee27dc 100644 (file)
@@ -583,6 +583,7 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
                model = cpumcf_z13_pmu_event_attr;
                break;
        case 0x3906:
+       case 0x3907:
                model = cpumcf_z14_pmu_event_attr;
                break;
        default:
index fc3b4aa..d82a9ec 100644 (file)
@@ -821,6 +821,7 @@ static int __init setup_hwcaps(void)
                strcpy(elf_platform, "z13");
                break;
        case 0x3906:
+       case 0x3907:
                strcpy(elf_platform, "z14");
                break;
        }
index b38d484..8b210ea 100644 (file)
 378  common    s390_guarded_storage    sys_s390_guarded_storage        compat_sys_s390_guarded_storage
 379  common    statx                   sys_statx                       compat_sys_statx
 380  common    s390_sthyi              sys_s390_sthyi                  compat_sys_s390_sthyi
+381  common    kexec_file_load         sys_kexec_file_load             compat_sys_kexec_file_load
diff --git a/arch/s390/purgatory/.gitignore b/arch/s390/purgatory/.gitignore
new file mode 100644 (file)
index 0000000..e9e66f1
--- /dev/null
@@ -0,0 +1,2 @@
+kexec-purgatory.c
+purgatory.ro
diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile
new file mode 100644 (file)
index 0000000..e9525bc
--- /dev/null
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0
+
+OBJECT_FILES_NON_STANDARD := y
+
+purgatory-y := head.o purgatory.o string.o sha256.o mem.o
+
+targets += $(purgatory-y) purgatory.ro kexec-purgatory.c
+PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
+
+$(obj)/sha256.o: $(srctree)/lib/sha256.c
+       $(call if_changed_rule,cc_o_c)
+
+$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S
+       $(call if_changed_rule,as_o_S)
+
+$(obj)/string.o: $(srctree)/arch/s390/lib/string.c
+       $(call if_changed_rule,cc_o_c)
+
+LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib
+LDFLAGS_purgatory.ro += -z nodefaultlib
+KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
+KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
+KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
+KBUILD_CFLAGS += -c -MD -Os -m64
+KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
+
+$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+               $(call if_changed,ld)
+
+CMD_BIN2C = $(objtree)/scripts/basic/bin2c
+quiet_cmd_bin2c = BIN2C   $@
+      cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@
+
+$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE
+       $(call if_changed,bin2c)
+
+obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o
diff --git a/arch/s390/purgatory/head.S b/arch/s390/purgatory/head.S
new file mode 100644 (file)
index 0000000..660c96a
--- /dev/null
@@ -0,0 +1,279 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/sigp.h>
+
+/* The purgatory is the code running between two kernels. It's main purpose
+ * is to verify that the next kernel was not corrupted after load and to
+ * start it.
+ *
+ * If the next kernel is a crash kernel there are some peculiarities to
+ * consider:
+ *
+ * First the purgatory is called twice. Once only to verify the
+ * sha digest. So if the crash kernel got corrupted the old kernel can try
+ * to trigger a stand-alone dumper. And once to actually load the crash kernel.
+ *
+ * Second the purgatory also has to swap the crash memory region with its
+ * destination at address 0. As the purgatory is part of crash memory this
+ * requires some finesse. The tactic here is that the purgatory first copies
+ * itself to the end of the destination and then swaps the rest of the
+ * memory running from there.
+ */
+
+#define bufsz purgatory_end-stack
+
+.macro MEMCPY dst,src,len
+       lgr     %r0,\dst
+       lgr     %r1,\len
+       lgr     %r2,\src
+       lgr     %r3,\len
+
+20:    mvcle   %r0,%r2,0
+       jo      20b
+.endm
+
+.macro MEMSWAP dst,src,buf,len
+10:    cghi    \len,bufsz
+       jh      11f
+       lgr     %r4,\len
+       j       12f
+11:    lghi    %r4,bufsz
+
+12:    MEMCPY  \buf,\dst,%r4
+       MEMCPY  \dst,\src,%r4
+       MEMCPY  \src,\buf,%r4
+
+       agr     \dst,%r4
+       agr     \src,%r4
+       sgr     \len,%r4
+
+       cghi    \len,0
+       jh      10b
+.endm
+
+.macro START_NEXT_KERNEL base
+       lg      %r4,kernel_entry-\base(%r13)
+       lg      %r5,load_psw_mask-\base(%r13)
+       ogr     %r4,%r5
+       stg     %r4,0(%r0)
+
+       xgr     %r0,%r0
+       diag    %r0,%r0,0x308
+.endm
+
+.text
+.align PAGE_SIZE
+ENTRY(purgatory_start)
+       /* The purgatory might be called after a diag308 so better set
+        * architecture and addressing mode.
+        */
+       lhi     %r1,1
+       sigp    %r1,%r0,SIGP_SET_ARCHITECTURE
+       sam64
+
+       larl    %r5,gprregs
+       stmg    %r6,%r15,0(%r5)
+
+       basr    %r13,0
+.base_crash:
+
+       /* Setup stack */
+       larl    %r15,purgatory_end
+       aghi    %r15,-160
+
+       /* If the next kernel is KEXEC_TYPE_CRASH the purgatory is called
+        * directly with a flag passed in %r2 whether the purgatory shall do
+        * checksum verification only (%r2 = 0 -> verification only).
+        *
+        * Check now and preserve over C function call by storing in
+        * %r10 whith
+        *      1 -> checksum verification only
+        *      0 -> load new kernel
+        */
+       lghi    %r10,0
+       lg      %r11,kernel_type-.base_crash(%r13)
+       cghi    %r11,1          /* KEXEC_TYPE_CRASH */
+       jne     .do_checksum_verification
+       cghi    %r2,0           /* checksum verification only */
+       jne     .do_checksum_verification
+       lghi    %r10,1
+
+.do_checksum_verification:
+       brasl   %r14,verify_sha256_digest
+
+       cghi    %r10,1          /* checksum verification only */
+       je      .return_old_kernel
+       cghi    %r2,0           /* checksum match */
+       jne     .disabled_wait
+
+       /* If the next kernel is a crash kernel the purgatory has to swap
+        * the mem regions first.
+        */
+       cghi    %r11,1 /* KEXEC_TYPE_CRASH */
+       je      .start_crash_kernel
+
+       /* start normal kernel */
+       START_NEXT_KERNEL .base_crash
+
+.return_old_kernel:
+       lmg     %r6,%r15,gprregs-.base_crash(%r13)
+       br      %r14
+
+.disabled_wait:
+       lpswe   disabled_wait_psw-.base_crash(%r13)
+
+.start_crash_kernel:
+       /* Location of purgatory_start in crash memory */
+       lgr     %r8,%r13
+       aghi    %r8,-(.base_crash-purgatory_start)
+
+       /* Destination for this code i.e. end of memory to be swapped. */
+       lg      %r9,crash_size-.base_crash(%r13)
+       aghi    %r9,-(purgatory_end-purgatory_start)
+
+       /* Destination in crash memory, i.e. same as r9 but in crash memory. */
+       lg      %r10,crash_start-.base_crash(%r13)
+       agr     %r10,%r9
+
+       /* Buffer location (in crash memory) and size. As the purgatory is
+        * behind the point of no return it can re-use the stack as buffer.
+        */
+       lghi    %r11,bufsz
+       larl    %r12,stack
+
+       MEMCPY  %r12,%r9,%r11   /* dst  -> (crash) buf */
+       MEMCPY  %r9,%r8,%r11    /* self -> dst */
+
+       /* Jump to new location. */
+       lgr     %r7,%r9
+       aghi    %r7,.jump_to_dst-purgatory_start
+       br      %r7
+
+.jump_to_dst:
+       basr    %r13,0
+.base_dst:
+
+       /* clear buffer */
+       MEMCPY  %r12,%r10,%r11  /* (crash) buf -> (crash) dst */
+
+       /* Load new buffer location after jump */
+       larl    %r7,stack
+       aghi    %r10,stack-purgatory_start
+       MEMCPY  %r10,%r7,%r11   /* (new) buf -> (crash) buf */
+
+       /* Now the code is set up to run from its designated location. Start
+        * swapping the rest of crash memory now.
+        *
+        * The registers will be used as follow:
+        *
+        *      %r0-%r4 reserved for macros defined above
+        *      %r5-%r6 tmp registers
+        *      %r7     pointer to current struct sha region
+        *      %r8     index to iterate over all sha regions
+        *      %r9     pointer in crash memory
+        *      %r10    pointer in old kernel
+        *      %r11    total size (still) to be moved
+        *      %r12    pointer to buffer
+        */
+       lgr     %r12,%r7
+       lgr     %r11,%r9
+       lghi    %r10,0
+       lg      %r9,crash_start-.base_dst(%r13)
+       lghi    %r8,16  /* KEXEC_SEGMENTS_MAX */
+       larl    %r7,purgatory_sha_regions
+
+       j .loop_first
+
+       /* Loop over all purgatory_sha_regions. */
+.loop_next:
+       aghi    %r8,-1
+       cghi    %r8,0
+       je      .loop_out
+
+       aghi    %r7,__KEXEC_SHA_REGION_SIZE
+
+.loop_first:
+       lg      %r5,__KEXEC_SHA_REGION_START(%r7)
+       cghi    %r5,0
+       je      .loop_next
+
+       /* Copy [end last sha region, start current sha region) */
+       /* Note: kexec_sha_region->start points in crash memory */
+       sgr     %r5,%r9
+       MEMCPY  %r9,%r10,%r5
+
+       agr     %r9,%r5
+       agr     %r10,%r5
+       sgr     %r11,%r5
+
+       /* Swap sha region */
+       lg      %r6,__KEXEC_SHA_REGION_LEN(%r7)
+       MEMSWAP %r9,%r10,%r12,%r6
+       sg      %r11,__KEXEC_SHA_REGION_LEN(%r7)
+       j       .loop_next
+
+.loop_out:
+       /* Copy rest of crash memory */
+       MEMCPY  %r9,%r10,%r11
+
+       /* start crash kernel */
+       START_NEXT_KERNEL .base_dst
+
+
+load_psw_mask:
+       .long   0x00080000,0x80000000
+
+       .align  8
+disabled_wait_psw:
+       .quad   0x0002000180000000
+       .quad   0x0000000000000000 + .do_checksum_verification
+
+gprregs:
+       .rept   10
+       .quad   0
+       .endr
+
+purgatory_sha256_digest:
+       .global purgatory_sha256_digest
+       .rept   32      /* SHA256_DIGEST_SIZE */
+       .byte   0
+       .endr
+
+purgatory_sha_regions:
+       .global purgatory_sha_regions
+       .rept   16 * __KEXEC_SHA_REGION_SIZE    /* KEXEC_SEGMENTS_MAX */
+       .byte   0
+       .endr
+
+kernel_entry:
+       .global kernel_entry
+       .quad   0
+
+kernel_type:
+       .global kernel_type
+       .quad   0
+
+crash_start:
+       .global crash_start
+       .quad   0
+
+crash_size:
+       .global crash_size
+       .quad   0
+
+       .align  PAGE_SIZE
+stack:
+       /* The buffer to move this code must be as big as the code. */
+       .skip   stack-purgatory_start
+       .align  PAGE_SIZE
+purgatory_end:
diff --git a/arch/s390/purgatory/purgatory.c b/arch/s390/purgatory/purgatory.c
new file mode 100644 (file)
index 0000000..4e2beb3
--- /dev/null
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Purgatory code running between two kernels.
+ *
+ * Copyright IBM Corp. 2018
+ *
+ * Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
+ */
+
+#include <linux/kexec.h>
+#include <linux/sha256.h>
+#include <linux/string.h>
+#include <asm/purgatory.h>
+
+struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX];
+u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE];
+
+u64 kernel_entry;
+u64 kernel_type;
+
+u64 crash_start;
+u64 crash_size;
+
+int verify_sha256_digest(void)
+{
+       struct kexec_sha_region *ptr, *end;
+       u8 digest[SHA256_DIGEST_SIZE];
+       struct sha256_state sctx;
+
+       sha256_init(&sctx);
+       end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions);
+
+       for (ptr = purgatory_sha_regions; ptr < end; ptr++)
+               sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len);
+
+       sha256_final(&sctx, digest);
+
+       if (memcmp(digest, purgatory_sha256_digest, sizeof(digest)))
+               return 1;
+
+       return 0;
+}
index c98b943..77076a1 100644 (file)
@@ -3028,10 +3028,27 @@ static struct intel_uncore_type bdx_uncore_cbox = {
        .format_group           = &hswep_uncore_cbox_format_group,
 };
 
+static struct intel_uncore_type bdx_uncore_sbox = {
+       .name                   = "sbox",
+       .num_counters           = 4,
+       .num_boxes              = 4,
+       .perf_ctr_bits          = 48,
+       .event_ctl              = HSWEP_S0_MSR_PMON_CTL0,
+       .perf_ctr               = HSWEP_S0_MSR_PMON_CTR0,
+       .event_mask             = HSWEP_S_MSR_PMON_RAW_EVENT_MASK,
+       .box_ctl                = HSWEP_S0_MSR_PMON_BOX_CTL,
+       .msr_offset             = HSWEP_SBOX_MSR_OFFSET,
+       .ops                    = &hswep_uncore_sbox_msr_ops,
+       .format_group           = &hswep_uncore_sbox_format_group,
+};
+
+#define BDX_MSR_UNCORE_SBOX    3
+
 static struct intel_uncore_type *bdx_msr_uncores[] = {
        &bdx_uncore_ubox,
        &bdx_uncore_cbox,
        &hswep_uncore_pcu,
+       &bdx_uncore_sbox,
        NULL,
 };
 
@@ -3043,10 +3060,25 @@ static struct event_constraint bdx_uncore_pcu_constraints[] = {
 
 void bdx_uncore_cpu_init(void)
 {
+       int pkg = topology_phys_to_logical_pkg(0);
+
        if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
                bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
        uncore_msr_uncores = bdx_msr_uncores;
 
+       /* BDX-DE doesn't have SBOX */
+       if (boot_cpu_data.x86_model == 86) {
+               uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
+       /* Detect systems with no SBOXes */
+       } else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) {
+               struct pci_dev *pdev;
+               u32 capid4;
+
+               pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3];
+               pci_read_config_dword(pdev, 0x94, &capid4);
+               if (((capid4 >> 6) & 0x3) == 0)
+                       bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL;
+       }
        hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints;
 }
 
@@ -3264,6 +3296,11 @@ static const struct pci_device_id bdx_uncore_pci_ids[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6f46),
                .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, 2),
        },
+       { /* PCU.3 (for Capability registers) */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0),
+               .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV,
+                                                  HSWEP_PCI_PCU_3),
+       },
        { /* end: all zeroes */ }
 };
 
index 386a690..219faae 100644 (file)
 #endif
 
 #ifndef __ASSEMBLY__
-#ifndef __BPF__
 /*
  * This output constraint should be used for any inline asm which has a "call"
  * instruction.  Otherwise the asm may be inserted before the frame pointer
 register unsigned long current_stack_pointer asm(_ASM_SP);
 #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
 #endif
-#endif
 
 #endif /* _ASM_X86_ASM_H */
index 949c977..c25775f 100644 (file)
@@ -1013,6 +1013,7 @@ struct kvm_x86_ops {
 
        bool (*has_wbinvd_exit)(void);
 
+       u64 (*read_l1_tsc_offset)(struct kvm_vcpu *vcpu);
        void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
index 4fa4206..21a1149 100644 (file)
@@ -749,13 +749,11 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
-extern void early_trap_init(void);
 void early_trap_pf_init(void);
 
 /* Defined in head.S */
 extern struct desc_ptr         early_gdt_descr;
 
-extern void cpu_set_gdt(int);
 extern void switch_to_new_gdt(int);
 extern void load_direct_gdt(int);
 extern void load_fixmap_gdt(int);
index dde444f..3b20607 100644 (file)
@@ -215,6 +215,10 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
        apic_id = processor->local_apic_id;
        enabled = processor->lapic_flags & ACPI_MADT_ENABLED;
 
+       /* Ignore invalid ID */
+       if (apic_id == 0xffffffff)
+               return 0;
+
        /*
         * We need to register disabled CPU as well to permit
         * counting disabled CPUs. This allows us to size
index 3182908..7326078 100644 (file)
@@ -398,11 +398,10 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
         * little bit simple
         */
        efi_map_sz = efi_get_runtime_map_size();
-       efi_map_sz = ALIGN(efi_map_sz, 16);
        params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
                                MAX_ELFCOREHDR_STR_LEN;
        params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
-       kbuf.bufsz = params_cmdline_sz + efi_map_sz +
+       kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
                                sizeof(struct setup_data) +
                                sizeof(struct efi_setup_data);
 
@@ -410,7 +409,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
        if (!params)
                return ERR_PTR(-ENOMEM);
        efi_map_offset = params_cmdline_sz;
-       efi_setup_data_offset = efi_map_offset + efi_map_sz;
+       efi_setup_data_offset = efi_map_offset + ALIGN(efi_map_sz, 16);
 
        /* Copy setup header onto bootparams. Documentation/x86/boot.txt */
        setup_header_size = 0x0202 + kernel[0x0201] - setup_hdr_offset;
index d41d896..c9b1402 100644 (file)
@@ -166,7 +166,7 @@ map_ldt_struct(struct mm_struct *mm, struct ldt_struct *ldt, int slot)
                 */
                pte_prot = __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL);
                /* Filter out unsuppored __PAGE_KERNEL* bits: */
-               pgprot_val(pte_prot) |= __supported_pte_mask;
+               pgprot_val(pte_prot) &= __supported_pte_mask;
                pte = pfn_pte(pfn, pte_prot);
                set_pte_at(mm, va, ptep, pte);
                pte_unmap_unlock(ptep, ptl);
diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c
deleted file mode 100644 (file)
index ac7ea3a..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Fallback functions when the main IOMMU code is not compiled in. This
-   code is roughly equivalent to i386. */
-#include <linux/dma-direct.h>
-#include <linux/scatterlist.h>
-#include <linux/string.h>
-#include <linux/gfp.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-
-#include <asm/processor.h>
-#include <asm/iommu.h>
-#include <asm/dma.h>
-
-#define NOMMU_MAPPING_ERROR            0
-
-static int
-check_addr(char *name, struct device *hwdev, dma_addr_t bus, size_t size)
-{
-       if (hwdev && !dma_capable(hwdev, bus, size)) {
-               if (*hwdev->dma_mask >= DMA_BIT_MASK(32))
-                       printk(KERN_ERR
-                           "nommu_%s: overflow %Lx+%zu of device mask %Lx\n",
-                               name, (long long)bus, size,
-                               (long long)*hwdev->dma_mask);
-               return 0;
-       }
-       return 1;
-}
-
-static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction dir,
-                                unsigned long attrs)
-{
-       dma_addr_t bus = phys_to_dma(dev, page_to_phys(page)) + offset;
-       WARN_ON(size == 0);
-       if (!check_addr("map_single", dev, bus, size))
-               return NOMMU_MAPPING_ERROR;
-       return bus;
-}
-
-/* Map a set of buffers described by scatterlist in streaming
- * mode for DMA.  This is the scatter-gather version of the
- * above pci_map_single interface.  Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length.  They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- *       DMA address/length pairs than there are SG table elements.
- *       (for example via virtual mapping capabilities)
- *       The routine returns the number of addr/length pairs actually
- *       used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
-static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
-                       int nents, enum dma_data_direction dir,
-                       unsigned long attrs)
-{
-       struct scatterlist *s;
-       int i;
-
-       WARN_ON(nents == 0 || sg[0].length == 0);
-
-       for_each_sg(sg, s, nents, i) {
-               BUG_ON(!sg_page(s));
-               s->dma_address = sg_phys(s);
-               if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
-                       return 0;
-               s->dma_length = s->length;
-       }
-       return nents;
-}
-
-static int nommu_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-       return dma_addr == NOMMU_MAPPING_ERROR;
-}
-
-const struct dma_map_ops nommu_dma_ops = {
-       .alloc                  = dma_generic_alloc_coherent,
-       .free                   = dma_generic_free_coherent,
-       .map_sg                 = nommu_map_sg,
-       .map_page               = nommu_map_page,
-       .is_phys                = 1,
-       .mapping_error          = nommu_mapping_error,
-       .dma_supported          = x86_dma_supported,
-};
index ff99e2b..45175b8 100644 (file)
@@ -77,6 +77,8 @@
 #include <asm/i8259.h>
 #include <asm/misc.h>
 #include <asm/qspinlock.h>
+#include <asm/intel-family.h>
+#include <asm/cpu_device_id.h>
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
@@ -390,15 +392,47 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
        return false;
 }
 
+/*
+ * Define snc_cpu[] for SNC (Sub-NUMA Cluster) CPUs.
+ *
+ * These are Intel CPUs that enumerate an LLC that is shared by
+ * multiple NUMA nodes. The LLC on these systems is shared for
+ * off-package data access but private to the NUMA node (half
+ * of the package) for on-package access.
+ *
+ * CPUID (the source of the information about the LLC) can only
+ * enumerate the cache as being shared *or* unshared, but not
+ * this particular configuration. The CPU in this case enumerates
+ * the cache to be shared across the entire package (spanning both
+ * NUMA nodes).
+ */
+
+static const struct x86_cpu_id snc_cpu[] = {
+       { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X },
+       {}
+};
+
 static bool match_llc(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
 {
        int cpu1 = c->cpu_index, cpu2 = o->cpu_index;
 
-       if (per_cpu(cpu_llc_id, cpu1) != BAD_APICID &&
-           per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2))
-               return topology_sane(c, o, "llc");
+       /* Do not match if we do not have a valid APICID for cpu: */
+       if (per_cpu(cpu_llc_id, cpu1) == BAD_APICID)
+               return false;
 
-       return false;
+       /* Do not match if LLC id does not match: */
+       if (per_cpu(cpu_llc_id, cpu1) != per_cpu(cpu_llc_id, cpu2))
+               return false;
+
+       /*
+        * Allow the SNC topology without warning. Return of false
+        * means 'c' does not share the LLC of 'o'. This will be
+        * reflected to userspace.
+        */
+       if (!topology_same_node(c, o) && x86_match_cpu(snc_cpu))
+               return false;
+
+       return topology_sane(c, o, "llc");
 }
 
 /*
@@ -456,7 +490,8 @@ static struct sched_domain_topology_level x86_topology[] = {
 
 /*
  * Set if a package/die has multiple NUMA nodes inside.
- * AMD Magny-Cours and Intel Cluster-on-Die have this.
+ * AMD Magny-Cours, Intel Cluster-on-Die, and Intel
+ * Sub-NUMA Clustering have this.
  */
 static bool x86_has_numa_in_package;
 
index ef32297..91e6da4 100644 (file)
@@ -317,7 +317,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2)
        hpet2 -= hpet1;
        tmp = ((u64)hpet2 * hpet_readl(HPET_PERIOD));
        do_div(tmp, 1000000);
-       do_div(deltatsc, tmp);
+       deltatsc = div64_u64(deltatsc, tmp);
 
        return (unsigned long) deltatsc;
 }
index b58787d..1fc05e4 100644 (file)
@@ -1423,12 +1423,23 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
        seg->base = 0;
 }
 
+static u64 svm_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
+{
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       if (is_guest_mode(vcpu))
+               return svm->nested.hsave->control.tsc_offset;
+
+       return vcpu->arch.tsc_offset;
+}
+
 static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        u64 g_tsc_offset = 0;
 
        if (is_guest_mode(vcpu)) {
+               /* Write L1's TSC offset.  */
                g_tsc_offset = svm->vmcb->control.tsc_offset -
                               svm->nested.hsave->control.tsc_offset;
                svm->nested.hsave->control.tsc_offset = offset;
@@ -3322,6 +3333,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
        /* Restore the original control entries */
        copy_vmcb_control_area(vmcb, hsave);
 
+       svm->vcpu.arch.tsc_offset = svm->vmcb->control.tsc_offset;
        kvm_clear_exception_queue(&svm->vcpu);
        kvm_clear_interrupt_queue(&svm->vcpu);
 
@@ -3482,10 +3494,12 @@ static void enter_svm_guest_mode(struct vcpu_svm *svm, u64 vmcb_gpa,
        /* We don't want to see VMMCALLs from a nested guest */
        clr_intercept(svm, INTERCEPT_VMMCALL);
 
+       svm->vcpu.arch.tsc_offset += nested_vmcb->control.tsc_offset;
+       svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset;
+
        svm->vmcb->control.virt_ext = nested_vmcb->control.virt_ext;
        svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
        svm->vmcb->control.int_state = nested_vmcb->control.int_state;
-       svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
        svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
        svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
 
@@ -4035,12 +4049,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        struct vcpu_svm *svm = to_svm(vcpu);
 
        switch (msr_info->index) {
-       case MSR_IA32_TSC: {
-               msr_info->data = svm->vmcb->control.tsc_offset +
-                       kvm_scale_tsc(vcpu, rdtsc());
-
-               break;
-       }
        case MSR_STAR:
                msr_info->data = svm->vmcb->save.star;
                break;
@@ -4193,9 +4201,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                svm->vmcb->save.g_pat = data;
                mark_dirty(svm->vmcb, VMCB_NPT);
                break;
-       case MSR_IA32_TSC:
-               kvm_write_tsc(vcpu, msr);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS))
@@ -5265,9 +5270,8 @@ static int svm_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
                }
 
                if (!ret && svm) {
-                       trace_kvm_pi_irte_update(svm->vcpu.vcpu_id,
-                                                host_irq, e->gsi,
-                                                vcpu_info.vector,
+                       trace_kvm_pi_irte_update(host_irq, svm->vcpu.vcpu_id,
+                                                e->gsi, vcpu_info.vector,
                                                 vcpu_info.pi_desc_addr, set);
                }
 
@@ -7102,6 +7106,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
 
        .has_wbinvd_exit = svm_has_wbinvd_exit,
 
+       .read_l1_tsc_offset = svm_read_l1_tsc_offset,
        .write_tsc_offset = svm_write_tsc_offset,
 
        .set_tdp_cr3 = set_tdp_cr3,
index aafcc98..aa66ccd 100644 (file)
@@ -2880,18 +2880,15 @@ static void setup_msrs(struct vcpu_vmx *vmx)
                vmx_update_msr_bitmap(&vmx->vcpu);
 }
 
-/*
- * reads and returns guest's timestamp counter "register"
- * guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
- * -- Intel TSC Scaling for Virtualization White Paper, sec 1.3
- */
-static u64 guest_read_tsc(struct kvm_vcpu *vcpu)
+static u64 vmx_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
 {
-       u64 host_tsc, tsc_offset;
+       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 
-       host_tsc = rdtsc();
-       tsc_offset = vmcs_read64(TSC_OFFSET);
-       return kvm_scale_tsc(vcpu, host_tsc) + tsc_offset;
+       if (is_guest_mode(vcpu) &&
+           (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING))
+               return vcpu->arch.tsc_offset - vmcs12->tsc_offset;
+
+       return vcpu->arch.tsc_offset;
 }
 
 /*
@@ -3524,9 +3521,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 #endif
        case MSR_EFER:
                return kvm_get_msr_common(vcpu, msr_info);
-       case MSR_IA32_TSC:
-               msr_info->data = guest_read_tsc(vcpu);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) &&
@@ -3646,9 +3640,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;
                vmcs_write64(GUEST_BNDCFGS, data);
                break;
-       case MSR_IA32_TSC:
-               kvm_write_tsc(vcpu, msr_info);
-               break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) &&
@@ -10608,6 +10599,16 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
        return true;
 }
 
+static int nested_vmx_check_apic_access_controls(struct kvm_vcpu *vcpu,
+                                         struct vmcs12 *vmcs12)
+{
+       if (nested_cpu_has2(vmcs12, SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) &&
+           !page_address_valid(vcpu, vmcs12->apic_access_addr))
+               return -EINVAL;
+       else
+               return 0;
+}
+
 static int nested_vmx_check_apicv_controls(struct kvm_vcpu *vcpu,
                                           struct vmcs12 *vmcs12)
 {
@@ -11176,11 +11177,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
                vmcs_write64(GUEST_IA32_PAT, vmx->vcpu.arch.pat);
        }
 
-       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
-               vmcs_write64(TSC_OFFSET,
-                       vcpu->arch.tsc_offset + vmcs12->tsc_offset);
-       else
-               vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
+       vmcs_write64(TSC_OFFSET, vcpu->arch.tsc_offset);
+
        if (kvm_has_tsc_control)
                decache_tsc_multiplier(vmx);
 
@@ -11299,6 +11297,9 @@ static int check_vmentry_prereqs(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
        if (nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12))
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
+       if (nested_vmx_check_apic_access_controls(vcpu, vmcs12))
+               return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
+
        if (nested_vmx_check_tpr_shadow_controls(vcpu, vmcs12))
                return VMXERR_ENTRY_INVALID_CONTROL_FIELD;
 
@@ -11420,6 +11421,7 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
        struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
        u32 msr_entry_idx;
        u32 exit_qual;
+       int r;
 
        enter_guest_mode(vcpu);
 
@@ -11429,26 +11431,21 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
        vmx_switch_vmcs(vcpu, &vmx->nested.vmcs02);
        vmx_segment_cache_clear(vmx);
 
-       if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual)) {
-               leave_guest_mode(vcpu);
-               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                                        EXIT_REASON_INVALID_STATE, exit_qual);
-               return 1;
-       }
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset += vmcs12->tsc_offset;
+
+       r = EXIT_REASON_INVALID_STATE;
+       if (prepare_vmcs02(vcpu, vmcs12, from_vmentry, &exit_qual))
+               goto fail;
 
        nested_get_vmcs12_pages(vcpu, vmcs12);
 
+       r = EXIT_REASON_MSR_LOAD_FAIL;
        msr_entry_idx = nested_vmx_load_msr(vcpu,
                                            vmcs12->vm_entry_msr_load_addr,
                                            vmcs12->vm_entry_msr_load_count);
-       if (msr_entry_idx) {
-               leave_guest_mode(vcpu);
-               vmx_switch_vmcs(vcpu, &vmx->vmcs01);
-               nested_vmx_entry_failure(vcpu, vmcs12,
-                               EXIT_REASON_MSR_LOAD_FAIL, msr_entry_idx);
-               return 1;
-       }
+       if (msr_entry_idx)
+               goto fail;
 
        /*
         * Note no nested_vmx_succeed or nested_vmx_fail here. At this point
@@ -11457,6 +11454,14 @@ static int enter_vmx_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
         * the success flag) when L2 exits (see nested_vmx_vmexit()).
         */
        return 0;
+
+fail:
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset -= vmcs12->tsc_offset;
+       leave_guest_mode(vcpu);
+       vmx_switch_vmcs(vcpu, &vmx->vmcs01);
+       nested_vmx_entry_failure(vcpu, vmcs12, r, exit_qual);
+       return 1;
 }
 
 /*
@@ -12028,6 +12033,9 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
 
        leave_guest_mode(vcpu);
 
+       if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
+               vcpu->arch.tsc_offset -= vmcs12->tsc_offset;
+
        if (likely(!vmx->fail)) {
                if (exit_reason == -1)
                        sync_vmcs12(vcpu, vmcs12);
@@ -12224,10 +12232,16 @@ static inline int u64_shl_div_u64(u64 a, unsigned int shift,
 
 static int vmx_set_hv_timer(struct kvm_vcpu *vcpu, u64 guest_deadline_tsc)
 {
-       struct vcpu_vmx *vmx = to_vmx(vcpu);
-       u64 tscl = rdtsc();
-       u64 guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
-       u64 delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
+       struct vcpu_vmx *vmx;
+       u64 tscl, guest_tscl, delta_tsc;
+
+       if (kvm_mwait_in_guest(vcpu->kvm))
+               return -EOPNOTSUPP;
+
+       vmx = to_vmx(vcpu);
+       tscl = rdtsc();
+       guest_tscl = kvm_read_l1_tsc(vcpu, tscl);
+       delta_tsc = max(guest_deadline_tsc, guest_tscl) - guest_tscl;
 
        /* Convert to host delta tsc if tsc scaling is enabled */
        if (vcpu->arch.tsc_scaling_ratio != kvm_default_tsc_scaling_ratio &&
@@ -12533,7 +12547,7 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
                vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu));
                vcpu_info.vector = irq.vector;
 
-               trace_kvm_pi_irte_update(vcpu->vcpu_id, host_irq, e->gsi,
+               trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
                                vcpu_info.vector, vcpu_info.pi_desc_addr, set);
 
                if (set)
@@ -12712,6 +12726,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
 
        .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
+       .read_l1_tsc_offset = vmx_read_l1_tsc_offset,
        .write_tsc_offset = vmx_write_tsc_offset,
 
        .set_tdp_cr3 = vmx_set_cr3,
index b2ff74b..51ecd38 100644 (file)
@@ -1490,7 +1490,7 @@ static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
 
 static void update_ia32_tsc_adjust_msr(struct kvm_vcpu *vcpu, s64 offset)
 {
-       u64 curr_offset = vcpu->arch.tsc_offset;
+       u64 curr_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
        vcpu->arch.ia32_tsc_adjust_msr += offset - curr_offset;
 }
 
@@ -1532,7 +1532,9 @@ static u64 kvm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
 
 u64 kvm_read_l1_tsc(struct kvm_vcpu *vcpu, u64 host_tsc)
 {
-       return vcpu->arch.tsc_offset + kvm_scale_tsc(vcpu, host_tsc);
+       u64 tsc_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
+
+       return tsc_offset + kvm_scale_tsc(vcpu, host_tsc);
 }
 EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
 
@@ -2362,6 +2364,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;
                vcpu->arch.smbase = data;
                break;
+       case MSR_IA32_TSC:
+               kvm_write_tsc(vcpu, msr_info);
+               break;
        case MSR_SMI_COUNT:
                if (!msr_info->host_initiated)
                        return 1;
@@ -2605,6 +2610,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_UCODE_REV:
                msr_info->data = vcpu->arch.microcode_version;
                break;
+       case MSR_IA32_TSC:
+               msr_info->data = kvm_scale_tsc(vcpu, rdtsc()) + vcpu->arch.tsc_offset;
+               break;
        case MSR_MTRRcap:
        case 0x200 ... 0x2ff:
                return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data);
@@ -2819,7 +2827,8 @@ out:
 static inline bool kvm_can_mwait_in_guest(void)
 {
        return boot_cpu_has(X86_FEATURE_MWAIT) &&
-               !boot_cpu_has_bug(X86_BUG_MONITOR);
+               !boot_cpu_has_bug(X86_BUG_MONITOR) &&
+               boot_cpu_has(X86_FEATURE_ARAT);
 }
 
 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
index 62a7e9f..cc7ff59 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
+#include <linux/highmem.h>
 
 #include <asm/pgtable.h>
 
@@ -334,16 +335,16 @@ static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
                           pgprotval_t eff_in, unsigned long P)
 {
        int i;
-       pte_t *start;
+       pte_t *pte;
        pgprotval_t prot, eff;
 
-       start = (pte_t *)pmd_page_vaddr(addr);
        for (i = 0; i < PTRS_PER_PTE; i++) {
-               prot = pte_flags(*start);
-               eff = effective_prot(eff_in, prot);
                st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
+               pte = pte_offset_map(&addr, st->current_address);
+               prot = pte_flags(*pte);
+               eff = effective_prot(eff_in, prot);
                note_page(m, st, __pgprot(prot), eff, 5);
-               start++;
+               pte_unmap(pte);
        }
 }
 #ifdef CONFIG_KASAN
index 48b14b5..ccf4a49 100644 (file)
@@ -98,7 +98,7 @@ static int set_up_temporary_text_mapping(pgd_t *pgd)
                set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        } else {
                /* No p4d for 4-level paging: point the pgd to the pud page table */
-               pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot));
+               pgd_t new_pgd = __pgd(__pa(pud) | pgprot_val(pgtable_prot));
                set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        }
 
index 44abb8a..be07660 100644 (file)
@@ -671,7 +671,7 @@ static void ia_tx_poll (IADEV *iadev) {
           if ((vcc->pop) && (skb1->len != 0))
           {
              vcc->pop(vcc, skb1);
-             IF_EVENT(printk("Tansmit Done - skb 0x%lx return\n",
+             IF_EVENT(printk("Transmit Done - skb 0x%lx return\n",
                                                           (long)skb1);)
           }
           else 
@@ -1665,7 +1665,7 @@ static void tx_intr(struct atm_dev *dev)
        status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);  
         if (status & TRANSMIT_DONE){
 
-           IF_EVENT(printk("Tansmit Done Intr logic run\n");)
+           IF_EVENT(printk("Transmit Done Intr logic run\n");)
            spin_lock_irqsave(&iadev->tx_lock, flags);
            ia_tx_poll(iadev);
            spin_unlock_irqrestore(&iadev->tx_lock, flags);
index 07dc541..8e8b04c 100644 (file)
@@ -732,6 +732,7 @@ static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts)
  */
 enum {
        Opt_queue_depth,
+       Opt_lock_timeout,
        Opt_last_int,
        /* int args above */
        Opt_last_string,
@@ -740,11 +741,13 @@ enum {
        Opt_read_write,
        Opt_lock_on_read,
        Opt_exclusive,
+       Opt_notrim,
        Opt_err
 };
 
 static match_table_t rbd_opts_tokens = {
        {Opt_queue_depth, "queue_depth=%d"},
+       {Opt_lock_timeout, "lock_timeout=%d"},
        /* int args above */
        /* string args above */
        {Opt_read_only, "read_only"},
@@ -753,20 +756,25 @@ static match_table_t rbd_opts_tokens = {
        {Opt_read_write, "rw"},         /* Alternate spelling */
        {Opt_lock_on_read, "lock_on_read"},
        {Opt_exclusive, "exclusive"},
+       {Opt_notrim, "notrim"},
        {Opt_err, NULL}
 };
 
 struct rbd_options {
        int     queue_depth;
+       unsigned long   lock_timeout;
        bool    read_only;
        bool    lock_on_read;
        bool    exclusive;
+       bool    trim;
 };
 
 #define RBD_QUEUE_DEPTH_DEFAULT        BLKDEV_MAX_RQ
+#define RBD_LOCK_TIMEOUT_DEFAULT 0  /* no timeout */
 #define RBD_READ_ONLY_DEFAULT  false
 #define RBD_LOCK_ON_READ_DEFAULT false
 #define RBD_EXCLUSIVE_DEFAULT  false
+#define RBD_TRIM_DEFAULT       true
 
 static int parse_rbd_opts_token(char *c, void *private)
 {
@@ -796,6 +804,14 @@ static int parse_rbd_opts_token(char *c, void *private)
                }
                rbd_opts->queue_depth = intval;
                break;
+       case Opt_lock_timeout:
+               /* 0 is "wait forever" (i.e. infinite timeout) */
+               if (intval < 0 || intval > INT_MAX / 1000) {
+                       pr_err("lock_timeout out of range\n");
+                       return -EINVAL;
+               }
+               rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
+               break;
        case Opt_read_only:
                rbd_opts->read_only = true;
                break;
@@ -808,6 +824,9 @@ static int parse_rbd_opts_token(char *c, void *private)
        case Opt_exclusive:
                rbd_opts->exclusive = true;
                break;
+       case Opt_notrim:
+               rbd_opts->trim = false;
+               break;
        default:
                /* libceph prints "bad option" msg */
                return -EINVAL;
@@ -1392,7 +1411,7 @@ static bool rbd_img_is_write(struct rbd_img_request *img_req)
        case OBJ_OP_DISCARD:
                return true;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -2466,7 +2485,7 @@ again:
                }
                return false;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -2494,7 +2513,7 @@ static bool __rbd_obj_handle_request(struct rbd_obj_request *obj_req)
                }
                return false;
        default:
-               rbd_assert(0);
+               BUG();
        }
 }
 
@@ -3533,9 +3552,22 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
 /*
  * lock_rwsem must be held for read
  */
-static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
+static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
 {
        DEFINE_WAIT(wait);
+       unsigned long timeout;
+       int ret = 0;
+
+       if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags))
+               return -EBLACKLISTED;
+
+       if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED)
+               return 0;
+
+       if (!may_acquire) {
+               rbd_warn(rbd_dev, "exclusive lock required");
+               return -EROFS;
+       }
 
        do {
                /*
@@ -3547,12 +3579,22 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
                prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait,
                                          TASK_UNINTERRUPTIBLE);
                up_read(&rbd_dev->lock_rwsem);
-               schedule();
+               timeout = schedule_timeout(ceph_timeout_jiffies(
+                                               rbd_dev->opts->lock_timeout));
                down_read(&rbd_dev->lock_rwsem);
-       } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
-                !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags));
+               if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
+                       ret = -EBLACKLISTED;
+                       break;
+               }
+               if (!timeout) {
+                       rbd_warn(rbd_dev, "timed out waiting for lock");
+                       ret = -ETIMEDOUT;
+                       break;
+               }
+       } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED);
 
        finish_wait(&rbd_dev->lock_waitq, &wait);
+       return ret;
 }
 
 static void rbd_queue_workfn(struct work_struct *work)
@@ -3638,19 +3680,10 @@ static void rbd_queue_workfn(struct work_struct *work)
            (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
        if (must_be_locked) {
                down_read(&rbd_dev->lock_rwsem);
-               if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
-                   !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
-                       if (rbd_dev->opts->exclusive) {
-                               rbd_warn(rbd_dev, "exclusive lock required");
-                               result = -EROFS;
-                               goto err_unlock;
-                       }
-                       rbd_wait_state_locked(rbd_dev);
-               }
-               if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
-                       result = -EBLACKLISTED;
+               result = rbd_wait_state_locked(rbd_dev,
+                                              !rbd_dev->opts->exclusive);
+               if (result)
                        goto err_unlock;
-               }
        }
 
        img_request = rbd_img_request_create(rbd_dev, op_type, snapc);
@@ -3902,7 +3935,8 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
 {
        struct gendisk *disk;
        struct request_queue *q;
-       u64 segment_size;
+       unsigned int objset_bytes =
+           rbd_dev->layout.object_size * rbd_dev->layout.stripe_count;
        int err;
 
        /* create gendisk info */
@@ -3942,20 +3976,19 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
        /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */
 
-       /* set io sizes to object size */
-       segment_size = rbd_obj_bytes(&rbd_dev->header);
-       blk_queue_max_hw_sectors(q, segment_size / SECTOR_SIZE);
+       blk_queue_max_hw_sectors(q, objset_bytes >> SECTOR_SHIFT);
        q->limits.max_sectors = queue_max_hw_sectors(q);
        blk_queue_max_segments(q, USHRT_MAX);
        blk_queue_max_segment_size(q, UINT_MAX);
-       blk_queue_io_min(q, segment_size);
-       blk_queue_io_opt(q, segment_size);
+       blk_queue_io_min(q, objset_bytes);
+       blk_queue_io_opt(q, objset_bytes);
 
-       /* enable the discard support */
-       blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
-       q->limits.discard_granularity = segment_size;
-       blk_queue_max_discard_sectors(q, segment_size / SECTOR_SIZE);
-       blk_queue_max_write_zeroes_sectors(q, segment_size / SECTOR_SIZE);
+       if (rbd_dev->opts->trim) {
+               blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
+               q->limits.discard_granularity = objset_bytes;
+               blk_queue_max_discard_sectors(q, objset_bytes >> SECTOR_SHIFT);
+               blk_queue_max_write_zeroes_sectors(q, objset_bytes >> SECTOR_SHIFT);
+       }
 
        if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC))
                q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
@@ -5179,8 +5212,10 @@ static int rbd_add_parse_args(const char *buf,
 
        rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
        rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
+       rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
        rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
        rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
+       rbd_opts->trim = RBD_TRIM_DEFAULT;
 
        copts = ceph_parse_options(options, mon_addrs,
                                        mon_addrs + mon_addrs_size - 1,
@@ -5216,6 +5251,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
 
 static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
 {
+       int ret;
+
        if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
                rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
                return -EINVAL;
@@ -5223,9 +5260,9 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
 
        /* FIXME: "rbd map --exclusive" should be in interruptible */
        down_read(&rbd_dev->lock_rwsem);
-       rbd_wait_state_locked(rbd_dev);
+       ret = rbd_wait_state_locked(rbd_dev, true);
        up_read(&rbd_dev->lock_rwsem);
-       if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
+       if (ret) {
                rbd_warn(rbd_dev, "failed to acquire exclusive lock");
                return -EROFS;
        }
index e027e7f..3cd3aae 100644 (file)
@@ -427,8 +427,9 @@ struct crng_state primary_crng = {
  * its value (from 0->1->2).
  */
 static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 0))
+#define crng_ready() (likely(crng_init > 1))
 static int crng_init_cnt = 0;
+static unsigned long crng_global_init_time = 0;
 #define CRNG_INIT_CNT_THRESH (2*CHACHA20_KEY_SIZE)
 static void _extract_crng(struct crng_state *crng,
                          __u32 out[CHACHA20_BLOCK_WORDS]);
@@ -787,6 +788,36 @@ static void crng_initialize(struct crng_state *crng)
        crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
 }
 
+#ifdef CONFIG_NUMA
+static void numa_crng_init(void)
+{
+       int i;
+       struct crng_state *crng;
+       struct crng_state **pool;
+
+       pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
+       for_each_online_node(i) {
+               crng = kmalloc_node(sizeof(struct crng_state),
+                                   GFP_KERNEL | __GFP_NOFAIL, i);
+               spin_lock_init(&crng->lock);
+               crng_initialize(crng);
+               pool[i] = crng;
+       }
+       mb();
+       if (cmpxchg(&crng_node_pool, NULL, pool)) {
+               for_each_node(i)
+                       kfree(pool[i]);
+               kfree(pool);
+       }
+}
+#else
+static void numa_crng_init(void) {}
+#endif
+
+/*
+ * crng_fast_load() can be called by code in the interrupt service
+ * path.  So we can't afford to dilly-dally.
+ */
 static int crng_fast_load(const char *cp, size_t len)
 {
        unsigned long flags;
@@ -794,7 +825,7 @@ static int crng_fast_load(const char *cp, size_t len)
 
        if (!spin_trylock_irqsave(&primary_crng.lock, flags))
                return 0;
-       if (crng_ready()) {
+       if (crng_init != 0) {
                spin_unlock_irqrestore(&primary_crng.lock, flags);
                return 0;
        }
@@ -813,6 +844,51 @@ static int crng_fast_load(const char *cp, size_t len)
        return 1;
 }
 
+/*
+ * crng_slow_load() is called by add_device_randomness, which has two
+ * attributes.  (1) We can't trust the buffer passed to it is
+ * guaranteed to be unpredictable (so it might not have any entropy at
+ * all), and (2) it doesn't have the performance constraints of
+ * crng_fast_load().
+ *
+ * So we do something more comprehensive which is guaranteed to touch
+ * all of the primary_crng's state, and which uses a LFSR with a
+ * period of 255 as part of the mixing algorithm.  Finally, we do
+ * *not* advance crng_init_cnt since buffer we may get may be something
+ * like a fixed DMI table (for example), which might very well be
+ * unique to the machine, but is otherwise unvarying.
+ */
+static int crng_slow_load(const char *cp, size_t len)
+{
+       unsigned long           flags;
+       static unsigned char    lfsr = 1;
+       unsigned char           tmp;
+       unsigned                i, max = CHACHA20_KEY_SIZE;
+       const char *            src_buf = cp;
+       char *                  dest_buf = (char *) &primary_crng.state[4];
+
+       if (!spin_trylock_irqsave(&primary_crng.lock, flags))
+               return 0;
+       if (crng_init != 0) {
+               spin_unlock_irqrestore(&primary_crng.lock, flags);
+               return 0;
+       }
+       if (len > max)
+               max = len;
+
+       for (i = 0; i < max ; i++) {
+               tmp = lfsr;
+               lfsr >>= 1;
+               if (tmp & 1)
+                       lfsr ^= 0xE1;
+               tmp = dest_buf[i % CHACHA20_KEY_SIZE];
+               dest_buf[i % CHACHA20_KEY_SIZE] ^= src_buf[i % len] ^ lfsr;
+               lfsr += (tmp << 3) | (tmp >> 5);
+       }
+       spin_unlock_irqrestore(&primary_crng.lock, flags);
+       return 1;
+}
+
 static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
 {
        unsigned long   flags;
@@ -831,7 +907,7 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
                _crng_backtrack_protect(&primary_crng, buf.block,
                                        CHACHA20_KEY_SIZE);
        }
-       spin_lock_irqsave(&primary_crng.lock, flags);
+       spin_lock_irqsave(&crng->lock, flags);
        for (i = 0; i < 8; i++) {
                unsigned long   rv;
                if (!arch_get_random_seed_long(&rv) &&
@@ -841,9 +917,10 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
        }
        memzero_explicit(&buf, sizeof(buf));
        crng->init_time = jiffies;
-       spin_unlock_irqrestore(&primary_crng.lock, flags);
+       spin_unlock_irqrestore(&crng->lock, flags);
        if (crng == &primary_crng && crng_init < 2) {
                invalidate_batched_entropy();
+               numa_crng_init();
                crng_init = 2;
                process_random_ready_list();
                wake_up_interruptible(&crng_init_wait);
@@ -856,8 +933,9 @@ static void _extract_crng(struct crng_state *crng,
 {
        unsigned long v, flags;
 
-       if (crng_init > 1 &&
-           time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))
+       if (crng_ready() &&
+           (time_after(crng_global_init_time, crng->init_time) ||
+            time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL)))
                crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL);
        spin_lock_irqsave(&crng->lock, flags);
        if (arch_get_random_long(&v))
@@ -981,10 +1059,8 @@ void add_device_randomness(const void *buf, unsigned int size)
        unsigned long time = random_get_entropy() ^ jiffies;
        unsigned long flags;
 
-       if (!crng_ready()) {
-               crng_fast_load(buf, size);
-               return;
-       }
+       if (!crng_ready() && size)
+               crng_slow_load(buf, size);
 
        trace_add_device_randomness(size, _RET_IP_);
        spin_lock_irqsave(&input_pool.lock, flags);
@@ -1139,7 +1215,7 @@ void add_interrupt_randomness(int irq, int irq_flags)
        fast_mix(fast_pool);
        add_interrupt_bench(cycles);
 
-       if (!crng_ready()) {
+       if (unlikely(crng_init == 0)) {
                if ((fast_pool->count >= 64) &&
                    crng_fast_load((char *) fast_pool->pool,
                                   sizeof(fast_pool->pool))) {
@@ -1680,28 +1756,10 @@ static void init_std_data(struct entropy_store *r)
  */
 static int rand_initialize(void)
 {
-#ifdef CONFIG_NUMA
-       int i;
-       struct crng_state *crng;
-       struct crng_state **pool;
-#endif
-
        init_std_data(&input_pool);
        init_std_data(&blocking_pool);
        crng_initialize(&primary_crng);
-
-#ifdef CONFIG_NUMA
-       pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
-       for_each_online_node(i) {
-               crng = kmalloc_node(sizeof(struct crng_state),
-                                   GFP_KERNEL | __GFP_NOFAIL, i);
-               spin_lock_init(&crng->lock);
-               crng_initialize(crng);
-               pool[i] = crng;
-       }
-       mb();
-       crng_node_pool = pool;
-#endif
+       crng_global_init_time = jiffies;
        return 0;
 }
 early_initcall(rand_initialize);
@@ -1875,6 +1933,14 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
                input_pool.entropy_count = 0;
                blocking_pool.entropy_count = 0;
                return 0;
+       case RNDRESEEDCRNG:
+               if (!capable(CAP_SYS_ADMIN))
+                       return -EPERM;
+               if (crng_init < 2)
+                       return -ENODATA;
+               crng_reseed(&primary_crng, NULL);
+               crng_global_init_time = jiffies - 1;
+               return 0;
        default:
                return -EINVAL;
        }
@@ -2212,7 +2278,7 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
 {
        struct entropy_store *poolp = &input_pool;
 
-       if (!crng_ready()) {
+       if (unlikely(crng_init == 0)) {
                crng_fast_load(buffer, count);
                return;
        }
index 9ee2888..8e8a097 100644 (file)
@@ -133,6 +133,14 @@ config VT8500_TIMER
        help
          Enables support for the VT8500 driver.
 
+config NPCM7XX_TIMER
+       bool "NPCM7xx timer driver" if COMPILE_TEST
+       depends on HAS_IOMEM
+       select CLKSRC_MMIO
+       help
+         Enable 24-bit TIMER0 and TIMER1 counters in the NPCM7xx architecture,
+         While TIMER0 serves as clockevent and TIMER1 serves as clocksource.
+
 config CADENCE_TTC_TIMER
        bool "Cadence TTC timer driver" if COMPILE_TEST
        depends on COMMON_CLK
index e8e76df..00caf37 100644 (file)
@@ -56,6 +56,7 @@ obj-$(CONFIG_CLKSRC_NPS)      += timer-nps.o
 obj-$(CONFIG_OXNAS_RPS_TIMER)  += timer-oxnas-rps.o
 obj-$(CONFIG_OWL_TIMER)                += owl-timer.o
 obj-$(CONFIG_SPRD_TIMER)       += timer-sprd.o
+obj-$(CONFIG_NPCM7XX_TIMER)    += timer-npcm7xx.o
 
 obj-$(CONFIG_ARC_TIMERS)               += arc_timer.o
 obj-$(CONFIG_ARM_ARCH_TIMER)           += arm_arch_timer.o
index 21bffdc..6c83184 100644 (file)
 #include <linux/of_irq.h>
 #include <linux/sched_clock.h>
 
+#define TPM_PARAM                      0x4
+#define TPM_PARAM_WIDTH_SHIFT          16
+#define TPM_PARAM_WIDTH_MASK           (0xff << 16)
 #define TPM_SC                         0x10
 #define TPM_SC_CMOD_INC_PER_CNT                (0x1 << 3)
 #define TPM_SC_CMOD_DIV_DEFAULT                0x3
+#define TPM_SC_CMOD_DIV_MAX            0x7
+#define TPM_SC_TOF_MASK                        (0x1 << 7)
 #define TPM_CNT                                0x14
 #define TPM_MOD                                0x18
 #define TPM_STATUS                     0x1c
 #define TPM_C0SC_MODE_SHIFT            2
 #define TPM_C0SC_MODE_MASK             0x3c
 #define TPM_C0SC_MODE_SW_COMPARE       0x4
+#define TPM_C0SC_CHF_MASK              (0x1 << 7)
 #define TPM_C0V                                0x24
 
+static int counter_width;
+static int rating;
 static void __iomem *timer_base;
 static struct clock_event_device clockevent_tpm;
 
@@ -83,10 +91,11 @@ static int __init tpm_clocksource_init(unsigned long rate)
        tpm_delay_timer.freq = rate;
        register_current_timer_delay(&tpm_delay_timer);
 
-       sched_clock_register(tpm_read_sched_clock, 32, rate);
+       sched_clock_register(tpm_read_sched_clock, counter_width, rate);
 
        return clocksource_mmio_init(timer_base + TPM_CNT, "imx-tpm",
-                                    rate, 200, 32, clocksource_mmio_readl_up);
+                                    rate, rating, counter_width,
+                                    clocksource_mmio_readl_up);
 }
 
 static int tpm_set_next_event(unsigned long delta,
@@ -105,7 +114,7 @@ static int tpm_set_next_event(unsigned long delta,
         * of writing CNT registers which may cause the min_delta event got
         * missed, so we need add a ETIME check here in case it happened.
         */
-       return (int)((next - now) <= 0) ? -ETIME : 0;
+       return (int)(next - now) <= 0 ? -ETIME : 0;
 }
 
 static int tpm_set_state_oneshot(struct clock_event_device *evt)
@@ -139,7 +148,6 @@ static struct clock_event_device clockevent_tpm = {
        .set_state_oneshot      = tpm_set_state_oneshot,
        .set_next_event         = tpm_set_next_event,
        .set_state_shutdown     = tpm_set_state_shutdown,
-       .rating                 = 200,
 };
 
 static int __init tpm_clockevent_init(unsigned long rate, int irq)
@@ -149,10 +157,11 @@ static int __init tpm_clockevent_init(unsigned long rate, int irq)
        ret = request_irq(irq, tpm_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
                          "i.MX7ULP TPM Timer", &clockevent_tpm);
 
+       clockevent_tpm.rating = rating;
        clockevent_tpm.cpumask = cpumask_of(0);
        clockevent_tpm.irq = irq;
-       clockevents_config_and_register(&clockevent_tpm,
-                                       rate, 300, 0xfffffffe);
+       clockevents_config_and_register(&clockevent_tpm, rate, 300,
+                                       GENMASK(counter_width - 1, 1));
 
        return ret;
 }
@@ -179,7 +188,7 @@ static int __init tpm_timer_init(struct device_node *np)
        ipg = of_clk_get_by_name(np, "ipg");
        per = of_clk_get_by_name(np, "per");
        if (IS_ERR(ipg) || IS_ERR(per)) {
-               pr_err("tpm: failed to get igp or per clk\n");
+               pr_err("tpm: failed to get ipg or per clk\n");
                ret = -ENODEV;
                goto err_clk_get;
        }
@@ -197,6 +206,11 @@ static int __init tpm_timer_init(struct device_node *np)
                goto err_per_clk_enable;
        }
 
+       counter_width = (readl(timer_base + TPM_PARAM) & TPM_PARAM_WIDTH_MASK)
+               >> TPM_PARAM_WIDTH_SHIFT;
+       /* use rating 200 for 32-bit counter and 150 for 16-bit counter */
+       rating = counter_width == 0x20 ? 200 : 150;
+
        /*
         * Initialize tpm module to a known state
         * 1) Counter disabled
@@ -205,16 +219,25 @@ static int __init tpm_timer_init(struct device_node *np)
         * 4) Channel0 disabled
         * 5) DMA transfers disabled
         */
+       /* make sure counter is disabled */
        writel(0, timer_base + TPM_SC);
+       /* TOF is W1C */
+       writel(TPM_SC_TOF_MASK, timer_base + TPM_SC);
        writel(0, timer_base + TPM_CNT);
-       writel(0, timer_base + TPM_C0SC);
+       /* CHF is W1C */
+       writel(TPM_C0SC_CHF_MASK, timer_base + TPM_C0SC);
 
-       /* increase per cnt, div 8 by default */
-       writel(TPM_SC_CMOD_INC_PER_CNT | TPM_SC_CMOD_DIV_DEFAULT,
+       /*
+        * increase per cnt,
+        * div 8 for 32-bit counter and div 128 for 16-bit counter
+        */
+       writel(TPM_SC_CMOD_INC_PER_CNT |
+               (counter_width == 0x20 ?
+               TPM_SC_CMOD_DIV_DEFAULT : TPM_SC_CMOD_DIV_MAX),
                     timer_base + TPM_SC);
 
        /* set MOD register to maximum for free running mode */
-       writel(0xffffffff, timer_base + TPM_MOD);
+       writel(GENMASK(counter_width - 1, 0), timer_base + TPM_MOD);
 
        rate = clk_get_rate(per) >> 3;
        ret = tpm_clocksource_init(rate);
diff --git a/drivers/clocksource/timer-npcm7xx.c b/drivers/clocksource/timer-npcm7xx.c
new file mode 100644 (file)
index 0000000..7a9bb55
--- /dev/null
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2014-2018 Nuvoton Technologies tomer.maimon@nuvoton.com
+ * All rights reserved.
+ *
+ * Copyright 2017 Google, Inc.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include "timer-of.h"
+
+/* Timers registers */
+#define NPCM7XX_REG_TCSR0      0x0 /* Timer 0 Control and Status Register */
+#define NPCM7XX_REG_TICR0      0x8 /* Timer 0 Initial Count Register */
+#define NPCM7XX_REG_TCSR1      0x4 /* Timer 1 Control and Status Register */
+#define NPCM7XX_REG_TICR1      0xc /* Timer 1 Initial Count Register */
+#define NPCM7XX_REG_TDR1       0x14 /* Timer 1 Data Register */
+#define NPCM7XX_REG_TISR       0x18 /* Timer Interrupt Status Register */
+
+/* Timers control */
+#define NPCM7XX_Tx_RESETINT            0x1f
+#define NPCM7XX_Tx_PERIOD              BIT(27)
+#define NPCM7XX_Tx_INTEN               BIT(29)
+#define NPCM7XX_Tx_COUNTEN             BIT(30)
+#define NPCM7XX_Tx_ONESHOT             0x0
+#define NPCM7XX_Tx_OPER                        GENMASK(3, 27)
+#define NPCM7XX_Tx_MIN_PRESCALE                0x1
+#define NPCM7XX_Tx_TDR_MASK_BITS       24
+#define NPCM7XX_Tx_MAX_CNT             0xFFFFFF
+#define NPCM7XX_T0_CLR_INT             0x1
+#define NPCM7XX_Tx_CLR_CSR             0x0
+
+/* Timers operating mode */
+#define NPCM7XX_START_PERIODIC_Tx (NPCM7XX_Tx_PERIOD | NPCM7XX_Tx_COUNTEN | \
+                                       NPCM7XX_Tx_INTEN | \
+                                       NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_ONESHOT_Tx (NPCM7XX_Tx_ONESHOT | NPCM7XX_Tx_COUNTEN | \
+                                       NPCM7XX_Tx_INTEN | \
+                                       NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_START_Tx (NPCM7XX_Tx_COUNTEN | NPCM7XX_Tx_PERIOD | \
+                               NPCM7XX_Tx_MIN_PRESCALE)
+
+#define NPCM7XX_DEFAULT_CSR (NPCM7XX_Tx_CLR_CSR | NPCM7XX_Tx_MIN_PRESCALE)
+
+static int npcm7xx_timer_resume(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_Tx_COUNTEN;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_shutdown(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_COUNTEN;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_oneshot(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_OPER;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_START_ONESHOT_Tx;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_timer_periodic(struct clock_event_device *evt)
+{
+       struct timer_of *to = to_timer_of(evt);
+       u32 val;
+
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val &= ~NPCM7XX_Tx_OPER;
+
+       writel(timer_of_period(to), timer_of_base(to) + NPCM7XX_REG_TICR0);
+       val |= NPCM7XX_START_PERIODIC_Tx;
+
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static int npcm7xx_clockevent_set_next_event(unsigned long evt,
+               struct clock_event_device *clk)
+{
+       struct timer_of *to = to_timer_of(clk);
+       u32 val;
+
+       writel(evt, timer_of_base(to) + NPCM7XX_REG_TICR0);
+       val = readl(timer_of_base(to) + NPCM7XX_REG_TCSR0);
+       val |= NPCM7XX_START_Tx;
+       writel(val, timer_of_base(to) + NPCM7XX_REG_TCSR0);
+
+       return 0;
+}
+
+static irqreturn_t npcm7xx_timer0_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+       struct timer_of *to = to_timer_of(evt);
+
+       writel(NPCM7XX_T0_CLR_INT, timer_of_base(to) + NPCM7XX_REG_TISR);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct timer_of npcm7xx_to = {
+       .flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+       .clkevt = {
+               .name               = "npcm7xx-timer0",
+               .features           = CLOCK_EVT_FEAT_PERIODIC |
+                                     CLOCK_EVT_FEAT_ONESHOT,
+               .set_next_event     = npcm7xx_clockevent_set_next_event,
+               .set_state_shutdown = npcm7xx_timer_shutdown,
+               .set_state_periodic = npcm7xx_timer_periodic,
+               .set_state_oneshot  = npcm7xx_timer_oneshot,
+               .tick_resume        = npcm7xx_timer_resume,
+               .rating             = 300,
+       },
+
+       .of_irq = {
+               .handler = npcm7xx_timer0_interrupt,
+               .flags = IRQF_TIMER | IRQF_IRQPOLL,
+       },
+};
+
+static void __init npcm7xx_clockevents_init(void)
+{
+       writel(NPCM7XX_DEFAULT_CSR,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR0);
+
+       writel(NPCM7XX_Tx_RESETINT,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TISR);
+
+       npcm7xx_to.clkevt.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&npcm7xx_to.clkevt,
+                                       timer_of_rate(&npcm7xx_to),
+                                       0x1, NPCM7XX_Tx_MAX_CNT);
+}
+
+static void __init npcm7xx_clocksource_init(void)
+{
+       u32 val;
+
+       writel(NPCM7XX_DEFAULT_CSR,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+       writel(NPCM7XX_Tx_MAX_CNT,
+               timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TICR1);
+
+       val = readl(timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+       val |= NPCM7XX_START_Tx;
+       writel(val, timer_of_base(&npcm7xx_to) + NPCM7XX_REG_TCSR1);
+
+       clocksource_mmio_init(timer_of_base(&npcm7xx_to) +
+                               NPCM7XX_REG_TDR1,
+                               "npcm7xx-timer1", timer_of_rate(&npcm7xx_to),
+                               200, (unsigned int)NPCM7XX_Tx_TDR_MASK_BITS,
+                               clocksource_mmio_readl_down);
+}
+
+static int __init npcm7xx_timer_init(struct device_node *np)
+{
+       int ret;
+
+       ret = timer_of_init(np, &npcm7xx_to);
+       if (ret)
+               return ret;
+
+       /* Clock input is divided by PRESCALE + 1 before it is fed */
+       /* to the counter */
+       npcm7xx_to.of_clk.rate = npcm7xx_to.of_clk.rate /
+               (NPCM7XX_Tx_MIN_PRESCALE + 1);
+
+       npcm7xx_clocksource_init();
+       npcm7xx_clockevents_init();
+
+       pr_info("Enabling NPCM7xx clocksource timer base: %px, IRQ: %d ",
+               timer_of_base(&npcm7xx_to), timer_of_irq(&npcm7xx_to));
+
+       return 0;
+}
+
+TIMER_OF_DECLARE(npcm7xx, "nuvoton,npcm750-timer", npcm7xx_timer_init);
+
index be86064..aff2c15 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/dax.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/mman.h>
 #include "dax-private.h"
 #include "dax.h"
 
@@ -540,6 +541,7 @@ static const struct file_operations dax_fops = {
        .release = dax_release,
        .get_unmapped_area = dax_get_unmapped_area,
        .mmap = dax_mmap,
+       .mmap_supported_flags = MAP_SYNC,
 };
 
 static void dev_dax_release(struct device *dev)
index f6cb502..25f064c 100644 (file)
@@ -138,13 +138,6 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc)
        lut = (struct drm_color_lut *)blob->data;
        lut_size = blob->length / sizeof(struct drm_color_lut);
 
-       if (__is_lut_linear(lut, lut_size)) {
-               /* Set to bypass if lut is set to linear */
-               stream->out_transfer_func->type = TF_TYPE_BYPASS;
-               stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-               return 0;
-       }
-
        gamma = dc_create_gamma();
        if (!gamma)
                return -ENOMEM;
index add9067..26fbeaf 100644 (file)
@@ -4743,23 +4743,27 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
 
        for (i=0; i < dep_table->count; i++) {
                if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
-                       break;
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
+                       return;
                }
        }
-       if (i == dep_table->count)
+       if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
                data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
+               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+       }
 
        dep_table = table_info->vdd_dep_on_sclk;
        odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
        for (i=0; i < dep_table->count; i++) {
                if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
-                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
-                       break;
+                       data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
+                       return;
                }
        }
-       if (i == dep_table->count)
+       if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
                data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
+               data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+       }
 }
 
 static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
index fb696e3..2f8a3b9 100644 (file)
@@ -412,8 +412,10 @@ typedef struct {
   QuadraticInt_t    ReservedEquation2;
   QuadraticInt_t    ReservedEquation3;
 
+       uint16_t     MinVoltageUlvGfx;
+       uint16_t     MinVoltageUlvSoc;
 
-  uint32_t     Reserved[15];
+       uint32_t     Reserved[14];
 
 
 
index 02a5092..e7f4fe2 100644 (file)
@@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
 {
        uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
        ssize_t ret;
+       int retry;
 
        if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
                return 0;
 
-       ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
-                                    &tmds_oen, sizeof(tmds_oen));
-       if (ret) {
-               DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
-                             enable ? "enable" : "disable");
-               return ret;
+       /*
+        * LSPCON adapters in low-power state may ignore the first write, so
+        * read back and verify the written value a few times.
+        */
+       for (retry = 0; retry < 3; retry++) {
+               uint8_t tmp;
+
+               ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
+                                            &tmds_oen, sizeof(tmds_oen));
+               if (ret) {
+                       DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
+                                     enable ? "enable" : "disable",
+                                     retry + 1);
+                       return ret;
+               }
+
+               ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
+                                           &tmp, sizeof(tmp));
+               if (ret) {
+                       DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
+                                     enable ? "enabling" : "disabling",
+                                     retry + 1);
+                       return ret;
+               }
+
+               if (tmp == tmds_oen)
+                       return 0;
        }
 
-       return 0;
+       DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
+                     enable ? "enabling" : "disabling");
+
+       return -EIO;
 }
 EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
 
index 0faaf82..f0e7917 100644 (file)
@@ -18,6 +18,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <uapi/drm/exynos_drm.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_iommu.h"
 #include "exynos_drm_crtc.h"
 
-#define to_exynos_fb(x)        container_of(x, struct exynos_drm_fb, fb)
-
-/*
- * exynos specific framebuffer structure.
- *
- * @fb: drm framebuffer obejct.
- * @exynos_gem: array of exynos specific gem object containing a gem object.
- */
-struct exynos_drm_fb {
-       struct drm_framebuffer  fb;
-       struct exynos_drm_gem   *exynos_gem[MAX_FB_BUFFER];
-       dma_addr_t                      dma_addr[MAX_FB_BUFFER];
-};
-
 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
                                    struct exynos_drm_gem *exynos_gem)
 {
@@ -66,40 +53,9 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev,
        return 0;
 }
 
-static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
-{
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-       unsigned int i;
-
-       drm_framebuffer_cleanup(fb);
-
-       for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
-               struct drm_gem_object *obj;
-
-               if (exynos_fb->exynos_gem[i] == NULL)
-                       continue;
-
-               obj = &exynos_fb->exynos_gem[i]->base;
-               drm_gem_object_unreference_unlocked(obj);
-       }
-
-       kfree(exynos_fb);
-       exynos_fb = NULL;
-}
-
-static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
-                                       struct drm_file *file_priv,
-                                       unsigned int *handle)
-{
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
-
-       return drm_gem_handle_create(file_priv,
-                                    &exynos_fb->exynos_gem[0]->base, handle);
-}
-
 static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
-       .destroy        = exynos_drm_fb_destroy,
-       .create_handle  = exynos_drm_fb_create_handle,
+       .destroy        = drm_gem_fb_destroy,
+       .create_handle  = drm_gem_fb_create_handle,
 };
 
 struct drm_framebuffer *
@@ -108,12 +64,12 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
                            struct exynos_drm_gem **exynos_gem,
                            int count)
 {
-       struct exynos_drm_fb *exynos_fb;
+       struct drm_framebuffer *fb;
        int i;
        int ret;
 
-       exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
-       if (!exynos_fb)
+       fb = kzalloc(sizeof(*fb), GFP_KERNEL);
+       if (!fb)
                return ERR_PTR(-ENOMEM);
 
        for (i = 0; i < count; i++) {
@@ -121,23 +77,21 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
                if (ret < 0)
                        goto err;
 
-               exynos_fb->exynos_gem[i] = exynos_gem[i];
-               exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr
-                                               + mode_cmd->offsets[i];
+               fb->obj[i] = &exynos_gem[i]->base;
        }
 
-       drm_helper_mode_fill_fb_struct(dev, &exynos_fb->fb, mode_cmd);
+       drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
 
-       ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
+       ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs);
        if (ret < 0) {
                DRM_ERROR("failed to initialize framebuffer\n");
                goto err;
        }
 
-       return &exynos_fb->fb;
+       return fb;
 
 err:
-       kfree(exynos_fb);
+       kfree(fb);
        return ERR_PTR(ret);
 }
 
@@ -191,12 +145,13 @@ err:
 
 dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
 {
-       struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+       struct exynos_drm_gem *exynos_gem;
 
        if (WARN_ON_ONCE(index >= MAX_FB_BUFFER))
                return 0;
 
-       return exynos_fb->dma_addr[index];
+       exynos_gem = to_exynos_gem(fb->obj[index]);
+       return exynos_gem->dma_addr + fb->offsets[index];
 }
 
 static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
index db6b94d..d85939b 100644 (file)
@@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
 {
        set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
                        s->workload->pending_events);
+       patch_value(s, cmd_ptr(s, 0), MI_NOOP);
        return 0;
 }
 
index dd96ffc..6d8180e 100644 (file)
@@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
 static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
 {
        struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
+       int pipe;
+
        vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
                        SDE_PORTC_HOTPLUG_CPT |
                        SDE_PORTD_HOTPLUG_CPT);
@@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
        if (IS_BROADWELL(dev_priv))
                vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
 
+       /* Disable Primary/Sprite/Cursor plane */
+       for_each_pipe(dev_priv, pipe) {
+               vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
+               vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
+               vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
+       }
+
        vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
 }
 
index b555eb2..6f4f8e9 100644 (file)
@@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
                      struct intel_vgpu_fb_info *fb_info)
 {
        gvt_dmabuf->drm_format = fb_info->drm_format;
+       gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
        gvt_dmabuf->width = fb_info->width;
        gvt_dmabuf->height = fb_info->height;
        gvt_dmabuf->stride = fb_info->stride;
index 6b50fe7..1c12068 100644 (file)
@@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
        plane->hw_format = fmt;
 
        plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
@@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
                        alpha_plane, alpha_force);
 
        plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
@@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
        plane->drm_format = drm_format;
 
        plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
-       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                            (unsigned long)plane->base);
+       if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
                return  -EINVAL;
-       }
 
        plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
        if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
-               gvt_vgpu_err("invalid gma address: %lx\n",
-                               (unsigned long)plane->base);
+               gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
+                               plane->base);
                return  -EINVAL;
        }
 
index d292812..78e55aa 100644 (file)
@@ -530,6 +530,16 @@ static void ggtt_set_guest_entry(struct intel_vgpu_mm *mm,
                           false, 0, mm->vgpu);
 }
 
+static void ggtt_get_host_entry(struct intel_vgpu_mm *mm,
+               struct intel_gvt_gtt_entry *entry, unsigned long index)
+{
+       struct intel_gvt_gtt_pte_ops *pte_ops = mm->vgpu->gvt->gtt.pte_ops;
+
+       GEM_BUG_ON(mm->type != INTEL_GVT_MM_GGTT);
+
+       pte_ops->get_entry(NULL, entry, index, false, 0, mm->vgpu);
+}
+
 static void ggtt_set_host_entry(struct intel_vgpu_mm *mm,
                struct intel_gvt_gtt_entry *entry, unsigned long index)
 {
@@ -1818,6 +1828,18 @@ int intel_vgpu_emulate_ggtt_mmio_read(struct intel_vgpu *vgpu, unsigned int off,
        return ret;
 }
 
+static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,
+               struct intel_gvt_gtt_entry *entry)
+{
+       struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
+       unsigned long pfn;
+
+       pfn = pte_ops->get_pfn(entry);
+       if (pfn != vgpu->gvt->gtt.scratch_mfn)
+               intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
+                                               pfn << PAGE_SHIFT);
+}
+
 static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
        void *p_data, unsigned int bytes)
 {
@@ -1844,10 +1866,10 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
 
        memcpy((void *)&e.val64 + (off & (info->gtt_entry_size - 1)), p_data,
                        bytes);
-       m = e;
 
        if (ops->test_present(&e)) {
                gfn = ops->get_pfn(&e);
+               m = e;
 
                /* one PTE update may be issued in multiple writes and the
                 * first write may not construct a valid gfn
@@ -1868,8 +1890,12 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
                        ops->set_pfn(&m, gvt->gtt.scratch_mfn);
                } else
                        ops->set_pfn(&m, dma_addr >> PAGE_SHIFT);
-       } else
+       } else {
+               ggtt_get_host_entry(ggtt_mm, &m, g_gtt_index);
+               ggtt_invalidate_pte(vgpu, &m);
                ops->set_pfn(&m, gvt->gtt.scratch_mfn);
+               ops->clear_present(&m);
+       }
 
 out:
        ggtt_set_host_entry(ggtt_mm, &m, g_gtt_index);
@@ -2030,7 +2056,7 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
                return PTR_ERR(gtt->ggtt_mm);
        }
 
-       intel_vgpu_reset_ggtt(vgpu);
+       intel_vgpu_reset_ggtt(vgpu, false);
 
        return create_scratch_page_tree(vgpu);
 }
@@ -2315,17 +2341,19 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu)
 /**
  * intel_vgpu_reset_ggtt - reset the GGTT entry
  * @vgpu: a vGPU
+ * @invalidate_old: invalidate old entries
  *
  * This function is called at the vGPU create stage
  * to reset all the GGTT entries.
  *
  */
-void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old)
 {
        struct intel_gvt *gvt = vgpu->gvt;
        struct drm_i915_private *dev_priv = gvt->dev_priv;
        struct intel_gvt_gtt_pte_ops *pte_ops = vgpu->gvt->gtt.pte_ops;
        struct intel_gvt_gtt_entry entry = {.type = GTT_TYPE_GGTT_PTE};
+       struct intel_gvt_gtt_entry old_entry;
        u32 index;
        u32 num_entries;
 
@@ -2334,13 +2362,23 @@ void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
 
        index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
        num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
-       while (num_entries--)
+       while (num_entries--) {
+               if (invalidate_old) {
+                       ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
+                       ggtt_invalidate_pte(vgpu, &old_entry);
+               }
                ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
+       }
 
        index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
        num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
-       while (num_entries--)
+       while (num_entries--) {
+               if (invalidate_old) {
+                       ggtt_get_host_entry(vgpu->gtt.ggtt_mm, &old_entry, index);
+                       ggtt_invalidate_pte(vgpu, &old_entry);
+               }
                ggtt_set_host_entry(vgpu->gtt.ggtt_mm, &entry, index++);
+       }
 
        ggtt_invalidate(dev_priv);
 }
@@ -2360,5 +2398,5 @@ void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu)
         * removing the shadow pages.
         */
        intel_vgpu_destroy_all_ppgtt_mm(vgpu);
-       intel_vgpu_reset_ggtt(vgpu);
+       intel_vgpu_reset_ggtt(vgpu, true);
 }
index a8b369c..3792f2b 100644 (file)
@@ -193,7 +193,7 @@ struct intel_vgpu_gtt {
 
 extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
 extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
-void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu, bool invalidate_old);
 void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu);
 
 extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
index 8c5d5d0..a33c1c3 100644 (file)
@@ -1150,6 +1150,7 @@ static int handle_g2v_notification(struct intel_vgpu *vgpu, int notification)
        switch (notification) {
        case VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE:
                root_entry_type = GTT_TYPE_PPGTT_ROOT_L3_ENTRY;
+               /* fall through */
        case VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE:
                mm = intel_vgpu_get_ppgtt_mm(vgpu, root_entry_type, pdps);
                return PTR_ERR_OR_ZERO(mm);
index c16a492..1466d87 100644 (file)
@@ -1301,7 +1301,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
 
        }
 
-       return 0;
+       return -ENOTTY;
 }
 
 static ssize_t
index 84ca369..3b4daaf 100644 (file)
@@ -1105,30 +1105,32 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        ret = i915_ggtt_probe_hw(dev_priv);
        if (ret)
-               return ret;
+               goto err_perf;
 
-       /* WARNING: Apparently we must kick fbdev drivers before vgacon,
-        * otherwise the vga fbdev driver falls over. */
+       /*
+        * WARNING: Apparently we must kick fbdev drivers before vgacon,
+        * otherwise the vga fbdev driver falls over.
+        */
        ret = i915_kick_out_firmware_fb(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        ret = i915_kick_out_vgacon(dev_priv);
        if (ret) {
                DRM_ERROR("failed to remove conflicting VGA console\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        ret = i915_ggtt_init_hw(dev_priv);
        if (ret)
-               return ret;
+               goto err_ggtt;
 
        ret = i915_ggtt_enable_hw(dev_priv);
        if (ret) {
                DRM_ERROR("failed to enable GGTT\n");
-               goto out_ggtt;
+               goto err_ggtt;
        }
 
        pci_set_master(pdev);
@@ -1139,7 +1141,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
 
-                       goto out_ggtt;
+                       goto err_ggtt;
                }
        }
 
@@ -1157,7 +1159,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
                if (ret) {
                        DRM_ERROR("failed to set DMA mask\n");
 
-                       goto out_ggtt;
+                       goto err_ggtt;
                }
        }
 
@@ -1190,13 +1192,14 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        ret = intel_gvt_init(dev_priv);
        if (ret)
-               goto out_ggtt;
+               goto err_ggtt;
 
        return 0;
 
-out_ggtt:
+err_ggtt:
        i915_ggtt_cleanup_hw(dev_priv);
-
+err_perf:
+       i915_perf_fini(dev_priv);
        return ret;
 }
 
index 8c170db..0414228 100644 (file)
@@ -728,7 +728,7 @@ static int eb_lookup_vmas(struct i915_execbuffer *eb)
 
                err = radix_tree_insert(handles_vma, handle, vma);
                if (unlikely(err)) {
-                       kfree(lut);
+                       kmem_cache_free(eb->i915->luts, lut);
                        goto err_obj;
                }
 
index d8feb90..f0519e3 100644 (file)
@@ -473,20 +473,37 @@ static u64 get_rc6(struct drm_i915_private *i915)
                spin_lock_irqsave(&i915->pmu.lock, flags);
                spin_lock(&kdev->power.lock);
 
-               if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
-                       i915->pmu.suspended_jiffies_last =
-                                               kdev->power.suspended_jiffies;
+               /*
+                * After the above branch intel_runtime_pm_get_if_in_use failed
+                * to get the runtime PM reference we cannot assume we are in
+                * runtime suspend since we can either: a) race with coming out
+                * of it before we took the power.lock, or b) there are other
+                * states than suspended which can bring us here.
+                *
+                * We need to double-check that we are indeed currently runtime
+                * suspended and if not we cannot do better than report the last
+                * known RC6 value.
+                */
+               if (kdev->power.runtime_status == RPM_SUSPENDED) {
+                       if (!i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur)
+                               i915->pmu.suspended_jiffies_last =
+                                                 kdev->power.suspended_jiffies;
 
-               val = kdev->power.suspended_jiffies -
-                     i915->pmu.suspended_jiffies_last;
-               val += jiffies - kdev->power.accounting_timestamp;
+                       val = kdev->power.suspended_jiffies -
+                             i915->pmu.suspended_jiffies_last;
+                       val += jiffies - kdev->power.accounting_timestamp;
 
-               spin_unlock(&kdev->power.lock);
+                       val = jiffies_to_nsecs(val);
+                       val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
 
-               val = jiffies_to_nsecs(val);
-               val += i915->pmu.sample[__I915_SAMPLE_RC6].cur;
-               i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+                       i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur = val;
+               } else if (i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur) {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6_ESTIMATED].cur;
+               } else {
+                       val = i915->pmu.sample[__I915_SAMPLE_RC6].cur;
+               }
 
+               spin_unlock(&kdev->power.lock);
                spin_unlock_irqrestore(&i915->pmu.lock, flags);
        }
 
index 709d6ca..3ea566f 100644 (file)
@@ -729,7 +729,7 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
        struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
        u32 tmp;
 
-       if (!IS_GEN9_BC(dev_priv))
+       if (!IS_GEN9(dev_priv))
                return;
 
        i915_audio_component_get_power(kdev);
index c5c7530..447b721 100644 (file)
@@ -1256,7 +1256,6 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
                return;
 
        aux_channel = child->aux_channel;
-       ddc_pin = child->ddc_pin;
 
        is_dvi = child->device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
        is_dp = child->device_type & DEVICE_TYPE_DISPLAYPORT_OUTPUT;
@@ -1303,9 +1302,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
                DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
 
        if (is_dvi) {
-               info->alternate_ddc_pin = map_ddc_pin(dev_priv, ddc_pin);
-
-               sanitize_ddc_pin(dev_priv, port);
+               ddc_pin = map_ddc_pin(dev_priv, child->ddc_pin);
+               if (intel_gmbus_is_valid_pin(dev_priv, ddc_pin)) {
+                       info->alternate_ddc_pin = ddc_pin;
+                       sanitize_ddc_pin(dev_priv, port);
+               } else {
+                       DRM_DEBUG_KMS("Port %c has invalid DDC pin %d, "
+                                     "sticking to defaults\n",
+                                     port_name(port), ddc_pin);
+               }
        }
 
        if (is_dp) {
index 697af5a..e3a5f67 100644 (file)
@@ -577,6 +577,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine)
                 * know the next preemption status we see corresponds
                 * to this ELSP update.
                 */
+               GEM_BUG_ON(!execlists_is_active(execlists,
+                                               EXECLISTS_ACTIVE_USER));
                GEM_BUG_ON(!port_count(&port[0]));
                if (port_count(&port[0]) > 1)
                        goto unlock;
@@ -738,6 +740,8 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)
                memset(port, 0, sizeof(*port));
                port++;
        }
+
+       execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER);
 }
 
 static void execlists_cancel_requests(struct intel_engine_cs *engine)
@@ -1001,6 +1005,11 @@ static void execlists_submission_tasklet(unsigned long data)
 
        if (fw)
                intel_uncore_forcewake_put(dev_priv, execlists->fw_domains);
+
+       /* If the engine is now idle, so should be the flag; and vice versa. */
+       GEM_BUG_ON(execlists_is_active(&engine->execlists,
+                                      EXECLISTS_ACTIVE_USER) ==
+                  !port_isset(engine->execlists.port));
 }
 
 static void queue_request(struct intel_engine_cs *engine,
index 2decc8e..add9cc9 100644 (file)
@@ -195,6 +195,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo)
        vc4_bo_set_label(obj, -1);
 
        if (bo->validated_shader) {
+               kfree(bo->validated_shader->uniform_addr_offsets);
                kfree(bo->validated_shader->texture_samples);
                kfree(bo->validated_shader);
                bo->validated_shader = NULL;
@@ -591,6 +592,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
        }
 
        if (bo->validated_shader) {
+               kfree(bo->validated_shader->uniform_addr_offsets);
                kfree(bo->validated_shader->texture_samples);
                kfree(bo->validated_shader);
                bo->validated_shader = NULL;
index d3f15bf..7cf82b0 100644 (file)
@@ -942,6 +942,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
 fail:
        kfree(validation_state.branch_targets);
        if (validated_shader) {
+               kfree(validated_shader->uniform_addr_offsets);
                kfree(validated_shader->texture_samples);
                kfree(validated_shader);
        }
index 5a3a7ea..0b5cc91 100644 (file)
 #define I2C_VENDOR_ID_HANTICK          0x0911
 #define I2C_PRODUCT_ID_HANTICK_5288    0x5288
 
+#define I2C_VENDOR_ID_RAYD             0x2386
+#define I2C_PRODUCT_ID_RAYD_3118       0x3118
+
 #define USB_VENDOR_ID_HANWANG          0x0b57
 #define USB_DEVICE_ID_HANWANG_TABLET_FIRST     0x5000
 #define USB_DEVICE_ID_HANWANG_TABLET_LAST      0x8fff
index 6836a85..930652c 100644 (file)
@@ -387,7 +387,8 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                break;
 
        case POWER_SUPPLY_PROP_CAPACITY:
-               if (dev->battery_report_type == HID_FEATURE_REPORT) {
+               if (dev->battery_status != HID_BATTERY_REPORTED &&
+                   !dev->battery_avoid_query) {
                        value = hidinput_query_battery_capacity(dev);
                        if (value < 0)
                                return value;
@@ -403,17 +404,17 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                break;
 
        case POWER_SUPPLY_PROP_STATUS:
-               if (!dev->battery_reported &&
-                   dev->battery_report_type == HID_FEATURE_REPORT) {
+               if (dev->battery_status != HID_BATTERY_REPORTED &&
+                   !dev->battery_avoid_query) {
                        value = hidinput_query_battery_capacity(dev);
                        if (value < 0)
                                return value;
 
                        dev->battery_capacity = value;
-                       dev->battery_reported = true;
+                       dev->battery_status = HID_BATTERY_QUERIED;
                }
 
-               if (!dev->battery_reported)
+               if (dev->battery_status == HID_BATTERY_UNKNOWN)
                        val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
                else if (dev->battery_capacity == 100)
                        val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -486,6 +487,14 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
        dev->battery_report_type = report_type;
        dev->battery_report_id = field->report->id;
 
+       /*
+        * Stylus is normally not connected to the device and thus we
+        * can't query the device and get meaningful battery strength.
+        * We have to wait for the device to report it on its own.
+        */
+       dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
+                                  field->physical == HID_DG_STYLUS;
+
        dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
        if (IS_ERR(dev->battery)) {
                error = PTR_ERR(dev->battery);
@@ -530,9 +539,10 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
 
        capacity = hidinput_scale_battery_capacity(dev, value);
 
-       if (!dev->battery_reported || capacity != dev->battery_capacity) {
+       if (dev->battery_status != HID_BATTERY_REPORTED ||
+           capacity != dev->battery_capacity) {
                dev->battery_capacity = capacity;
-               dev->battery_reported = true;
+               dev->battery_status = HID_BATTERY_REPORTED;
                power_supply_changed(dev->battery);
        }
 }
index fbfcc80..b39844a 100644 (file)
@@ -192,6 +192,11 @@ static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t
        int ret = 0, len;
        unsigned char report_number;
 
+       if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
+               ret = -ENODEV;
+               goto out;
+       }
+
        dev = hidraw_table[minor]->hid;
 
        if (!dev->ll_driver->raw_request) {
index 97689e9..9633286 100644 (file)
@@ -47,6 +47,7 @@
 /* quirks to control the device */
 #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV       BIT(0)
 #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET       BIT(1)
+#define I2C_HID_QUIRK_RESEND_REPORT_DESCR      BIT(2)
 
 /* flags */
 #define I2C_HID_STARTED                0
@@ -171,6 +172,8 @@ static const struct i2c_hid_quirks {
                I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
        { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
                I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
+       { I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
+               I2C_HID_QUIRK_RESEND_REPORT_DESCR },
        { 0, 0 }
 };
 
@@ -1220,6 +1223,16 @@ static int i2c_hid_resume(struct device *dev)
        if (ret)
                return ret;
 
+       /* RAYDIUM device (2386:3118) need to re-send report descr cmd
+        * after resume, after this it will be back normal.
+        * otherwise it issues too many incomplete reports.
+        */
+       if (ihid->quirks & I2C_HID_QUIRK_RESEND_REPORT_DESCR) {
+               ret = i2c_hid_command(client, &hid_report_descr_cmd, NULL, 0);
+               if (ret)
+                       return ret;
+       }
+
        if (hid->driver && hid->driver->reset_resume) {
                ret = hid->driver->reset_resume(hid);
                return ret;
index 6da16a8..5f947ec 100644 (file)
@@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(int tool_id)
        return tool_type;
 }
 
+static void wacom_exit_report(struct wacom_wac *wacom)
+{
+       struct input_dev *input = wacom->pen_input;
+       struct wacom_features *features = &wacom->features;
+       unsigned char *data = wacom->data;
+       int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
+
+       /*
+        * Reset all states otherwise we lose the initial states
+        * when in-prox next time
+        */
+       input_report_abs(input, ABS_X, 0);
+       input_report_abs(input, ABS_Y, 0);
+       input_report_abs(input, ABS_DISTANCE, 0);
+       input_report_abs(input, ABS_TILT_X, 0);
+       input_report_abs(input, ABS_TILT_Y, 0);
+       if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+               input_report_key(input, BTN_LEFT, 0);
+               input_report_key(input, BTN_MIDDLE, 0);
+               input_report_key(input, BTN_RIGHT, 0);
+               input_report_key(input, BTN_SIDE, 0);
+               input_report_key(input, BTN_EXTRA, 0);
+               input_report_abs(input, ABS_THROTTLE, 0);
+               input_report_abs(input, ABS_RZ, 0);
+       } else {
+               input_report_abs(input, ABS_PRESSURE, 0);
+               input_report_key(input, BTN_STYLUS, 0);
+               input_report_key(input, BTN_STYLUS2, 0);
+               input_report_key(input, BTN_TOUCH, 0);
+               input_report_abs(input, ABS_WHEEL, 0);
+               if (features->type >= INTUOS3S)
+                       input_report_abs(input, ABS_Z, 0);
+       }
+       input_report_key(input, wacom->tool[idx], 0);
+       input_report_abs(input, ABS_MISC, 0); /* reset tool id */
+       input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+       wacom->id[idx] = 0;
+}
+
 static int wacom_intuos_inout(struct wacom_wac *wacom)
 {
        struct wacom_features *features = &wacom->features;
@@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                if (!wacom->id[idx])
                        return 1;
 
-               /*
-                * Reset all states otherwise we lose the initial states
-                * when in-prox next time
-                */
-               input_report_abs(input, ABS_X, 0);
-               input_report_abs(input, ABS_Y, 0);
-               input_report_abs(input, ABS_DISTANCE, 0);
-               input_report_abs(input, ABS_TILT_X, 0);
-               input_report_abs(input, ABS_TILT_Y, 0);
-               if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
-                       input_report_key(input, BTN_LEFT, 0);
-                       input_report_key(input, BTN_MIDDLE, 0);
-                       input_report_key(input, BTN_RIGHT, 0);
-                       input_report_key(input, BTN_SIDE, 0);
-                       input_report_key(input, BTN_EXTRA, 0);
-                       input_report_abs(input, ABS_THROTTLE, 0);
-                       input_report_abs(input, ABS_RZ, 0);
-               } else {
-                       input_report_abs(input, ABS_PRESSURE, 0);
-                       input_report_key(input, BTN_STYLUS, 0);
-                       input_report_key(input, BTN_STYLUS2, 0);
-                       input_report_key(input, BTN_TOUCH, 0);
-                       input_report_abs(input, ABS_WHEEL, 0);
-                       if (features->type >= INTUOS3S)
-                               input_report_abs(input, ABS_Z, 0);
-               }
-               input_report_key(input, wacom->tool[idx], 0);
-               input_report_abs(input, ABS_MISC, 0); /* reset tool id */
-               input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-               wacom->id[idx] = 0;
+               wacom_exit_report(wacom);
                return 2;
        }
 
@@ -1235,6 +1245,12 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                if (!valid)
                        continue;
 
+               if (!prox) {
+                       wacom->shared->stylus_in_proximity = false;
+                       wacom_exit_report(wacom);
+                       input_sync(pen_input);
+                       return;
+               }
                if (range) {
                        input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
                        input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
index a6e8707..5336bbd 100644 (file)
@@ -68,12 +68,12 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
                goto _do;
 
        {
-               char _dup[len + 1];
                char *dup, *tok, *name, *val;
                int tmp;
 
-               strcpy(_dup, arg);
-               dup = _dup;
+               dup = kstrdup(arg, GFP_ATOMIC);
+               if (!dup)
+                       return;
 
                while ((tok = strsep(&dup, ","))) {
                        if (!strlen(tok))
@@ -89,6 +89,8 @@ void dsp_hwec_enable(struct dsp *dsp, const char *arg)
                                        deftaps = tmp;
                        }
                }
+
+               kfree(dup);
        }
 
 _do:
index 21d50e4..b05022f 100644 (file)
@@ -279,7 +279,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
                  u16 timebase, u8 *buf, int len)
 {
        u8 *p;
-       u8 frame[len + 32];
+       u8 frame[MAX_DFRAME_LEN_L1 + 32];
        struct socket *socket = NULL;
 
        if (debug & DEBUG_L1OIP_MSG)
@@ -902,7 +902,11 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
+                       /*
+                        * This is technically bounded by L1OIP_MAX_PERFRAME but
+                        * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
+                        */
+                       ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
                        l1oip_socket_send(hc, 0, dch->slot, 0,
                                          hc->chan[dch->slot].tx_counter++, p, ll);
                        p += ll;
@@ -1140,7 +1144,11 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
+                       /*
+                        * This is technically bounded by L1OIP_MAX_PERFRAME but
+                        * MAX_DFRAME_LEN_L1 < L1OIP_MAX_PERFRAME
+                        */
+                       ll = (l < MAX_DFRAME_LEN_L1) ? l : MAX_DFRAME_LEN_L1;
                        l1oip_socket_send(hc, hc->codec, bch->slot, 0,
                                          hc->chan[bch->slot].tx_counter, p, ll);
                        hc->chan[bch->slot].tx_counter += ll;
index 3bea45e..c208c01 100644 (file)
@@ -9256,8 +9256,10 @@ void md_reload_sb(struct mddev *mddev, int nr)
        check_sb_changes(mddev, rdev);
 
        /* Read all rdev's to update recovery_offset */
-       rdev_for_each_rcu(rdev, mddev)
-               read_rdev(mddev, rdev);
+       rdev_for_each_rcu(rdev, mddev) {
+               if (!test_bit(Faulty, &rdev->flags))
+                       read_rdev(mddev, rdev);
+       }
 }
 EXPORT_SYMBOL(md_reload_sb);
 
index e2943fb..e9e3308 100644 (file)
@@ -854,7 +854,7 @@ static void flush_pending_writes(struct r1conf *conf)
  *    there is no normal IO happeing.  It must arrange to call
  *    lower_barrier when the particular background IO completes.
  */
-static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
+static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr)
 {
        int idx = sector_to_idx(sector_nr);
 
@@ -885,13 +885,23 @@ static void raise_barrier(struct r1conf *conf, sector_t sector_nr)
         *    max resync count which allowed on current I/O barrier bucket.
         */
        wait_event_lock_irq(conf->wait_barrier,
-                           !conf->array_frozen &&
+                           (!conf->array_frozen &&
                             !atomic_read(&conf->nr_pending[idx]) &&
-                            atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH,
+                            atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) ||
+                               test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery),
                            conf->resync_lock);
 
+       if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
+               atomic_dec(&conf->barrier[idx]);
+               spin_unlock_irq(&conf->resync_lock);
+               wake_up(&conf->wait_barrier);
+               return -EINTR;
+       }
+
        atomic_inc(&conf->nr_sync_pending);
        spin_unlock_irq(&conf->resync_lock);
+
+       return 0;
 }
 
 static void lower_barrier(struct r1conf *conf, sector_t sector_nr)
@@ -1092,6 +1102,8 @@ static void alloc_behind_master_bio(struct r1bio *r1_bio,
                goto skip_copy;
        }
 
+       behind_bio->bi_write_hint = bio->bi_write_hint;
+
        while (i < vcnt && size) {
                struct page *page;
                int len = min_t(int, PAGE_SIZE, size);
@@ -2662,9 +2674,12 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
 
        bitmap_cond_end_sync(mddev->bitmap, sector_nr,
                mddev_is_clustered(mddev) && (sector_nr + 2 * RESYNC_SECTORS > conf->cluster_sync_high));
-       r1_bio = raid1_alloc_init_r1buf(conf);
 
-       raise_barrier(conf, sector_nr);
+
+       if (raise_barrier(conf, sector_nr))
+               return 0;
+
+       r1_bio = raid1_alloc_init_r1buf(conf);
 
        rcu_read_lock();
        /*
index 8e0acd1..6af946d 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
  *   need a custom accessor.
  */
 
+static unsigned long global_flags;
+/*
+ * Workaround for avoiding to use RX DMAC by multiple channels.
+ * On R-Car H3 ES1.* and M3-W ES1.0, when multiple SDHI channels use
+ * RX DMAC simultaneously, sometimes hundreds of bytes data are not
+ * stored into the system memory even if the DMAC interrupt happened.
+ * So, this driver then uses one RX DMAC channel only.
+ */
+#define SDHI_INTERNAL_DMAC_ONE_RX_ONLY 0
+#define SDHI_INTERNAL_DMAC_RX_IN_USE   1
+
 /* Definitions for sampling clocks */
 static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
        {
@@ -126,6 +138,9 @@ renesas_sdhi_internal_dmac_abort_dma(struct tmio_mmc_host *host) {
        renesas_sdhi_internal_dmac_dm_write(host, DM_CM_RST,
                                            RST_RESERVED_BITS | val);
 
+       if (host->data && host->data->flags & MMC_DATA_READ)
+               clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
        renesas_sdhi_internal_dmac_enable_dma(host, true);
 }
 
@@ -155,6 +170,9 @@ renesas_sdhi_internal_dmac_start_dma(struct tmio_mmc_host *host,
        if (data->flags & MMC_DATA_READ) {
                dtran_mode |= DTRAN_MODE_CH_NUM_CH1;
                dir = DMA_FROM_DEVICE;
+               if (test_bit(SDHI_INTERNAL_DMAC_ONE_RX_ONLY, &global_flags) &&
+                   test_and_set_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags))
+                       goto force_pio;
        } else {
                dtran_mode |= DTRAN_MODE_CH_NUM_CH0;
                dir = DMA_TO_DEVICE;
@@ -208,6 +226,9 @@ static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg)
        renesas_sdhi_internal_dmac_enable_dma(host, false);
        dma_unmap_sg(&host->pdev->dev, host->sg_ptr, host->sg_len, dir);
 
+       if (dir == DMA_FROM_DEVICE)
+               clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags);
+
        tmio_mmc_do_data_irq(host);
 out:
        spin_unlock_irq(&host->lock);
@@ -251,18 +272,24 @@ static const struct tmio_mmc_dma_ops renesas_sdhi_internal_dmac_dma_ops = {
  * implementation as others may use a different implementation.
  */
 static const struct soc_device_attribute gen3_soc_whitelist[] = {
-        { .soc_id = "r8a7795", .revision = "ES1.*" },
-        { .soc_id = "r8a7795", .revision = "ES2.0" },
-        { .soc_id = "r8a7796", .revision = "ES1.0" },
-        { .soc_id = "r8a77995", .revision = "ES1.0" },
-        { /* sentinel */ }
+       { .soc_id = "r8a7795", .revision = "ES1.*",
+         .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
+       { .soc_id = "r8a7795", .revision = "ES2.0" },
+       { .soc_id = "r8a7796", .revision = "ES1.0",
+         .data = (void *)BIT(SDHI_INTERNAL_DMAC_ONE_RX_ONLY) },
+       { .soc_id = "r8a77995", .revision = "ES1.0" },
+       { /* sentinel */ }
 };
 
 static int renesas_sdhi_internal_dmac_probe(struct platform_device *pdev)
 {
-       if (!soc_device_match(gen3_soc_whitelist))
+       const struct soc_device_attribute *soc = soc_device_match(gen3_soc_whitelist);
+
+       if (!soc)
                return -ENODEV;
 
+       global_flags |= (unsigned long)soc->data;
+
        return renesas_sdhi_probe(pdev, &renesas_sdhi_internal_dmac_dma_ops);
 }
 
index 787434e..78c25ad 100644 (file)
@@ -1312,7 +1312,7 @@ static void amd_enable_manual_tuning(struct pci_dev *pdev)
        pci_write_config_dword(pdev, AMD_SD_MISC_CONTROL, val);
 }
 
-static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
+static int amd_execute_tuning_hs200(struct sdhci_host *host, u32 opcode)
 {
        struct sdhci_pci_slot *slot = sdhci_priv(host);
        struct pci_dev *pdev = slot->chip->pdev;
@@ -1351,6 +1351,27 @@ static int amd_execute_tuning(struct sdhci_host *host, u32 opcode)
        return 0;
 }
 
+static int amd_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       /* AMD requires custom HS200 tuning */
+       if (host->timing == MMC_TIMING_MMC_HS200)
+               return amd_execute_tuning_hs200(host, opcode);
+
+       /* Otherwise perform standard SDHCI tuning */
+       return sdhci_execute_tuning(mmc, opcode);
+}
+
+static int amd_probe_slot(struct sdhci_pci_slot *slot)
+{
+       struct mmc_host_ops *ops = &slot->host->mmc_host_ops;
+
+       ops->execute_tuning = amd_execute_tuning;
+
+       return 0;
+}
+
 static int amd_probe(struct sdhci_pci_chip *chip)
 {
        struct pci_dev  *smbus_dev;
@@ -1385,12 +1406,12 @@ static const struct sdhci_ops amd_sdhci_pci_ops = {
        .set_bus_width                  = sdhci_set_bus_width,
        .reset                          = sdhci_reset,
        .set_uhs_signaling              = sdhci_set_uhs_signaling,
-       .platform_execute_tuning        = amd_execute_tuning,
 };
 
 static const struct sdhci_pci_fixes sdhci_amd = {
        .probe          = amd_probe,
        .ops            = &amd_sdhci_pci_ops,
+       .probe_slot     = amd_probe_slot,
 };
 
 static const struct pci_device_id pci_ids[] = {
index ac7694c..a036c49 100644 (file)
@@ -285,10 +285,18 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
                               struct sk_buff_head *rxq)
 {
        u16 buf[4] = { 0 }, status, seq_id;
-       u64 ns, timelo, timehi;
        struct skb_shared_hwtstamps *shwt;
+       struct sk_buff_head received;
+       u64 ns, timelo, timehi;
+       unsigned long flags;
        int err;
 
+       /* The latched timestamp belongs to one of the received frames. */
+       __skb_queue_head_init(&received);
+       spin_lock_irqsave(&rxq->lock, flags);
+       skb_queue_splice_tail_init(rxq, &received);
+       spin_unlock_irqrestore(&rxq->lock, flags);
+
        mutex_lock(&chip->reg_lock);
        err = mv88e6xxx_port_ptp_read(chip, ps->port_id,
                                      reg, buf, ARRAY_SIZE(buf));
@@ -311,7 +319,7 @@ static void mv88e6xxx_get_rxts(struct mv88e6xxx_chip *chip,
        /* Since the device can only handle one time stamp at a time,
         * we purge any extra frames from the queue.
         */
-       for ( ; skb; skb = skb_dequeue(rxq)) {
+       for ( ; skb; skb = __skb_dequeue(&received)) {
                if (mv88e6xxx_ts_valid(status) && seq_match(skb, seq_id)) {
                        ns = timehi << 16 | timelo;
 
index 1f622ca..8ba14ae 100644 (file)
@@ -1927,22 +1927,39 @@ static char *bnxt_parse_pkglog(int desired_field, u8 *data, size_t datalen)
        return retval;
 }
 
-static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen)
+static void bnxt_get_pkgver(struct net_device *dev)
 {
+       struct bnxt *bp = netdev_priv(dev);
        u16 index = 0;
-       u32 datalen;
+       char *pkgver;
+       u32 pkglen;
+       u8 *pkgbuf;
+       int len;
 
        if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG,
                                 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
-                                &index, NULL, &datalen) != 0)
-               return NULL;
+                                &index, NULL, &pkglen) != 0)
+               return;
 
-       memset(buf, 0, buflen);
-       if (bnxt_get_nvram_item(dev, index, 0, datalen, buf) != 0)
-               return NULL;
+       pkgbuf = kzalloc(pkglen, GFP_KERNEL);
+       if (!pkgbuf) {
+               dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n",
+                       pkglen);
+               return;
+       }
+
+       if (bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf))
+               goto err;
 
-       return bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, buf,
-               datalen);
+       pkgver = bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, pkgbuf,
+                                  pkglen);
+       if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
+               len = strlen(bp->fw_ver_str);
+               snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
+                        "/pkg %s", pkgver);
+       }
+err:
+       kfree(pkgbuf);
 }
 
 static int bnxt_get_eeprom(struct net_device *dev,
@@ -2615,22 +2632,10 @@ void bnxt_ethtool_init(struct bnxt *bp)
        struct hwrm_selftest_qlist_input req = {0};
        struct bnxt_test_info *test_info;
        struct net_device *dev = bp->dev;
-       char *pkglog;
        int i, rc;
 
-       pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL);
-       if (pkglog) {
-               char *pkgver;
-               int len;
+       bnxt_get_pkgver(dev);
 
-               pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH);
-               if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
-                       len = strlen(bp->fw_ver_str);
-                       snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
-                                "/pkg %s", pkgver);
-               }
-               kfree(pkglog);
-       }
        if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp))
                return;
 
index 73f2249..8344481 100644 (file)
@@ -59,8 +59,6 @@ enum bnxt_nvm_directory_type {
 #define BNX_DIR_ATTR_NO_CHKSUM                 (1 << 0)
 #define BNX_DIR_ATTR_PROP_STREAM               (1 << 1)
 
-#define BNX_PKG_LOG_MAX_LENGTH                 4096
-
 enum bnxnvm_pkglog_field_index {
        BNX_PKG_LOG_FIELD_IDX_INSTALLED_TIMESTAMP       = 0,
        BNX_PKG_LOG_FIELD_IDX_PKG_DESCRIPTION           = 1,
index 3e62692..fa5b30f 100644 (file)
@@ -87,7 +87,7 @@ do { \
 
 #define HNAE_AE_REGISTER 0x1
 
-#define RCB_RING_NAME_LEN 16
+#define RCB_RING_NAME_LEN (IFNAMSIZ + 4)
 
 #define HNAE_LOWEST_LATENCY_COAL_PARAM 30
 #define HNAE_LOW_LATENCY_COAL_PARAM    80
index aad5658..2df01ad 100644 (file)
@@ -794,46 +794,61 @@ static int ibmvnic_login(struct net_device *netdev)
 {
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
        unsigned long timeout = msecs_to_jiffies(30000);
-       struct device *dev = &adapter->vdev->dev;
+       int retry_count = 0;
        int rc;
 
        do {
-               if (adapter->renegotiate) {
-                       adapter->renegotiate = false;
+               if (retry_count > IBMVNIC_MAX_QUEUES) {
+                       netdev_warn(netdev, "Login attempts exceeded\n");
+                       return -1;
+               }
+
+               adapter->init_done_rc = 0;
+               reinit_completion(&adapter->init_done);
+               rc = send_login(adapter);
+               if (rc) {
+                       netdev_warn(netdev, "Unable to login\n");
+                       return rc;
+               }
+
+               if (!wait_for_completion_timeout(&adapter->init_done,
+                                                timeout)) {
+                       netdev_warn(netdev, "Login timed out\n");
+                       return -1;
+               }
+
+               if (adapter->init_done_rc == PARTIALSUCCESS) {
+                       retry_count++;
                        release_sub_crqs(adapter, 1);
 
+                       adapter->init_done_rc = 0;
                        reinit_completion(&adapter->init_done);
                        send_cap_queries(adapter);
                        if (!wait_for_completion_timeout(&adapter->init_done,
                                                         timeout)) {
-                               dev_err(dev, "Capabilities query timeout\n");
+                               netdev_warn(netdev,
+                                           "Capabilities query timed out\n");
                                return -1;
                        }
+
                        rc = init_sub_crqs(adapter);
                        if (rc) {
-                               dev_err(dev,
-                                       "Initialization of SCRQ's failed\n");
+                               netdev_warn(netdev,
+                                           "SCRQ initialization failed\n");
                                return -1;
                        }
+
                        rc = init_sub_crq_irqs(adapter);
                        if (rc) {
-                               dev_err(dev,
-                                       "Initialization of SCRQ's irqs failed\n");
+                               netdev_warn(netdev,
+                                           "SCRQ irq initialization failed\n");
                                return -1;
                        }
-               }
-
-               reinit_completion(&adapter->init_done);
-               rc = send_login(adapter);
-               if (rc) {
-                       dev_err(dev, "Unable to attempt device login\n");
-                       return rc;
-               } else if (!wait_for_completion_timeout(&adapter->init_done,
-                                                timeout)) {
-                       dev_err(dev, "Login timeout\n");
+               } else if (adapter->init_done_rc) {
+                       netdev_warn(netdev, "Adapter login failed\n");
                        return -1;
                }
-       } while (adapter->renegotiate);
+       } while (adapter->init_done_rc == PARTIALSUCCESS);
 
        /* handle pending MAC address changes after successful login */
        if (adapter->mac_change_pending) {
@@ -1034,16 +1049,14 @@ static int __ibmvnic_open(struct net_device *netdev)
                netdev_dbg(netdev, "Enabling rx_scrq[%d] irq\n", i);
                if (prev_state == VNIC_CLOSED)
                        enable_irq(adapter->rx_scrq[i]->irq);
-               else
-                       enable_scrq_irq(adapter, adapter->rx_scrq[i]);
+               enable_scrq_irq(adapter, adapter->rx_scrq[i]);
        }
 
        for (i = 0; i < adapter->req_tx_queues; i++) {
                netdev_dbg(netdev, "Enabling tx_scrq[%d] irq\n", i);
                if (prev_state == VNIC_CLOSED)
                        enable_irq(adapter->tx_scrq[i]->irq);
-               else
-                       enable_scrq_irq(adapter, adapter->tx_scrq[i]);
+               enable_scrq_irq(adapter, adapter->tx_scrq[i]);
        }
 
        rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
@@ -1184,6 +1197,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
                        if (adapter->tx_scrq[i]->irq) {
                                netdev_dbg(netdev,
                                           "Disabling tx_scrq[%d] irq\n", i);
+                               disable_scrq_irq(adapter, adapter->tx_scrq[i]);
                                disable_irq(adapter->tx_scrq[i]->irq);
                        }
        }
@@ -1193,6 +1207,7 @@ static void ibmvnic_disable_irqs(struct ibmvnic_adapter *adapter)
                        if (adapter->rx_scrq[i]->irq) {
                                netdev_dbg(netdev,
                                           "Disabling rx_scrq[%d] irq\n", i);
+                               disable_scrq_irq(adapter, adapter->rx_scrq[i]);
                                disable_irq(adapter->rx_scrq[i]->irq);
                        }
                }
@@ -1828,7 +1843,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
        for (i = 0; i < adapter->req_rx_queues; i++)
                napi_schedule(&adapter->napi[i]);
 
-       if (adapter->reset_reason != VNIC_RESET_FAILOVER)
+       if (adapter->reset_reason != VNIC_RESET_FAILOVER &&
+           adapter->reset_reason != VNIC_RESET_CHANGE_PARAM)
                netdev_notify_peers(netdev);
 
        netif_carrier_on(netdev);
@@ -2601,12 +2617,19 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
 {
        struct device *dev = &adapter->vdev->dev;
        unsigned long rc;
+       u64 val;
 
        if (scrq->hw_irq > 0x100000000ULL) {
                dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
                return 1;
        }
 
+       val = (0xff000000) | scrq->hw_irq;
+       rc = plpar_hcall_norets(H_EOI, val);
+       if (rc)
+               dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
+                       val, rc);
+
        rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
                                H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
        if (rc)
@@ -3170,7 +3193,7 @@ static int send_version_xchg(struct ibmvnic_adapter *adapter)
 struct vnic_login_client_data {
        u8      type;
        __be16  len;
-       char    name;
+       char    name[];
 } __packed;
 
 static int vnic_client_data_len(struct ibmvnic_adapter *adapter)
@@ -3199,21 +3222,21 @@ static void vnic_add_client_data(struct ibmvnic_adapter *adapter,
        vlcd->type = 1;
        len = strlen(os_name) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, os_name, len);
-       vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
+       strncpy(vlcd->name, os_name, len);
+       vlcd = (struct vnic_login_client_data *)(vlcd->name + len);
 
        /* Type 2 - LPAR name */
        vlcd->type = 2;
        len = strlen(utsname()->nodename) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, utsname()->nodename, len);
-       vlcd = (struct vnic_login_client_data *)((char *)&vlcd->name + len);
+       strncpy(vlcd->name, utsname()->nodename, len);
+       vlcd = (struct vnic_login_client_data *)(vlcd->name + len);
 
        /* Type 3 - device name */
        vlcd->type = 3;
        len = strlen(adapter->netdev->name) + 1;
        vlcd->len = cpu_to_be16(len);
-       strncpy(&vlcd->name, adapter->netdev->name, len);
+       strncpy(vlcd->name, adapter->netdev->name, len);
 }
 
 static int send_login(struct ibmvnic_adapter *adapter)
@@ -3942,7 +3965,7 @@ static int handle_login_rsp(union ibmvnic_crq *login_rsp_crq,
         * to resend the login buffer with fewer queues requested.
         */
        if (login_rsp_crq->generic.rc.code) {
-               adapter->renegotiate = true;
+               adapter->init_done_rc = login_rsp_crq->generic.rc.code;
                complete(&adapter->init_done);
                return 0;
        }
index 99c0b58..22391e8 100644 (file)
@@ -1035,7 +1035,6 @@ struct ibmvnic_adapter {
 
        struct ibmvnic_sub_crq_queue **tx_scrq;
        struct ibmvnic_sub_crq_queue **rx_scrq;
-       bool renegotiate;
 
        /* rx structs */
        struct napi_struct *napi;
index 54a0389..4202f9b 100644 (file)
@@ -663,7 +663,7 @@ enum mvpp2_tag_type {
 #define MVPP2_PE_VID_FILT_RANGE_END     (MVPP2_PRS_TCAM_SRAM_SIZE - 31)
 #define MVPP2_PE_VID_FILT_RANGE_START   (MVPP2_PE_VID_FILT_RANGE_END - \
                                         MVPP2_PRS_VLAN_FILT_RANGE_SIZE + 1)
-#define MVPP2_PE_LAST_FREE_TID          (MVPP2_PE_VID_FILT_RANGE_START - 1)
+#define MVPP2_PE_LAST_FREE_TID          (MVPP2_PE_MAC_RANGE_START - 1)
 #define MVPP2_PE_IP6_EXT_PROTO_UN      (MVPP2_PRS_TCAM_SRAM_SIZE - 30)
 #define MVPP2_PE_IP6_ADDR_UN           (MVPP2_PRS_TCAM_SRAM_SIZE - 29)
 #define MVPP2_PE_IP4_ADDR_UN           (MVPP2_PRS_TCAM_SRAM_SIZE - 28)
@@ -916,6 +916,8 @@ static struct {
 
 #define MVPP2_MIB_COUNTERS_STATS_DELAY         (1 * HZ)
 
+#define MVPP2_DESC_DMA_MASK    DMA_BIT_MASK(40)
+
 /* Definitions */
 
 /* Shared Packet Processor resources */
@@ -1429,7 +1431,7 @@ static dma_addr_t mvpp2_txdesc_dma_addr_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return tx_desc->pp21.buf_dma_addr;
        else
-               return tx_desc->pp22.buf_dma_addr_ptp & GENMASK_ULL(40, 0);
+               return tx_desc->pp22.buf_dma_addr_ptp & MVPP2_DESC_DMA_MASK;
 }
 
 static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
@@ -1447,7 +1449,7 @@ static void mvpp2_txdesc_dma_addr_set(struct mvpp2_port *port,
        } else {
                u64 val = (u64)addr;
 
-               tx_desc->pp22.buf_dma_addr_ptp &= ~GENMASK_ULL(40, 0);
+               tx_desc->pp22.buf_dma_addr_ptp &= ~MVPP2_DESC_DMA_MASK;
                tx_desc->pp22.buf_dma_addr_ptp |= val;
                tx_desc->pp22.packet_offset = offset;
        }
@@ -1507,7 +1509,7 @@ static dma_addr_t mvpp2_rxdesc_dma_addr_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return rx_desc->pp21.buf_dma_addr;
        else
-               return rx_desc->pp22.buf_dma_addr_key_hash & GENMASK_ULL(40, 0);
+               return rx_desc->pp22.buf_dma_addr_key_hash & MVPP2_DESC_DMA_MASK;
 }
 
 static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
@@ -1516,7 +1518,7 @@ static unsigned long mvpp2_rxdesc_cookie_get(struct mvpp2_port *port,
        if (port->priv->hw_version == MVPP21)
                return rx_desc->pp21.buf_cookie;
        else
-               return rx_desc->pp22.buf_cookie_misc & GENMASK_ULL(40, 0);
+               return rx_desc->pp22.buf_cookie_misc & MVPP2_DESC_DMA_MASK;
 }
 
 static size_t mvpp2_rxdesc_size_get(struct mvpp2_port *port,
@@ -8789,7 +8791,7 @@ static int mvpp2_probe(struct platform_device *pdev)
        }
 
        if (priv->hw_version == MVPP22) {
-               err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40));
+               err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK);
                if (err)
                        goto err_mg_clk;
                /* Sadly, the BM pools all share the same register to
index 3735c09..577659f 100644 (file)
@@ -258,9 +258,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
        case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
                nfp_tunnel_keep_alive(app, skb);
                break;
-       case NFP_FLOWER_CMSG_TYPE_TUN_NEIGH:
-               /* Acks from the NFP that the route is added - ignore. */
-               break;
        default:
                nfp_flower_cmsg_warn(app, "Cannot handle invalid repr control type %u\n",
                                     type);
@@ -275,18 +272,49 @@ out:
 
 void nfp_flower_cmsg_process_rx(struct work_struct *work)
 {
+       struct sk_buff_head cmsg_joined;
        struct nfp_flower_priv *priv;
        struct sk_buff *skb;
 
        priv = container_of(work, struct nfp_flower_priv, cmsg_work);
+       skb_queue_head_init(&cmsg_joined);
+
+       spin_lock_bh(&priv->cmsg_skbs_high.lock);
+       skb_queue_splice_tail_init(&priv->cmsg_skbs_high, &cmsg_joined);
+       spin_unlock_bh(&priv->cmsg_skbs_high.lock);
 
-       while ((skb = skb_dequeue(&priv->cmsg_skbs)))
+       spin_lock_bh(&priv->cmsg_skbs_low.lock);
+       skb_queue_splice_tail_init(&priv->cmsg_skbs_low, &cmsg_joined);
+       spin_unlock_bh(&priv->cmsg_skbs_low.lock);
+
+       while ((skb = __skb_dequeue(&cmsg_joined)))
                nfp_flower_cmsg_process_one_rx(priv->app, skb);
 }
 
-void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
+static void
+nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
 {
        struct nfp_flower_priv *priv = app->priv;
+       struct sk_buff_head *skb_head;
+
+       if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
+           type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
+               skb_head = &priv->cmsg_skbs_high;
+       else
+               skb_head = &priv->cmsg_skbs_low;
+
+       if (skb_queue_len(skb_head) >= NFP_FLOWER_WORKQ_MAX_SKBS) {
+               nfp_flower_cmsg_warn(app, "Dropping queued control messages\n");
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
+       skb_queue_tail(skb_head, skb);
+       schedule_work(&priv->cmsg_work);
+}
+
+void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
+{
        struct nfp_flower_cmsg_hdr *cmsg_hdr;
 
        cmsg_hdr = nfp_flower_cmsg_get_hdr(skb);
@@ -306,8 +334,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
                   nfp_flower_process_mtu_ack(app, skb)) {
                /* Handle MTU acks outside wq to prevent RTNL conflict. */
                dev_consume_skb_any(skb);
+       } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) {
+               /* Acks from the NFP that the route is added - ignore. */
+               dev_consume_skb_any(skb);
        } else {
-               skb_queue_tail(&priv->cmsg_skbs, skb);
-               schedule_work(&priv->cmsg_work);
+               nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
        }
 }
index 96bc0e3..b6c0fd0 100644 (file)
 #define NFP_FL_IPV4_TUNNEL_TYPE                GENMASK(7, 4)
 #define NFP_FL_IPV4_PRE_TUN_INDEX      GENMASK(2, 0)
 
+#define NFP_FLOWER_WORKQ_MAX_SKBS      30000
+
 #define nfp_flower_cmsg_warn(app, fmt, args...)                         \
        do {                                                            \
                if (net_ratelimit())                                    \
index 6357e07..ad02592 100644 (file)
@@ -519,7 +519,8 @@ static int nfp_flower_init(struct nfp_app *app)
 
        app->priv = app_priv;
        app_priv->app = app;
-       skb_queue_head_init(&app_priv->cmsg_skbs);
+       skb_queue_head_init(&app_priv->cmsg_skbs_high);
+       skb_queue_head_init(&app_priv->cmsg_skbs_low);
        INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
        init_waitqueue_head(&app_priv->reify_wait_queue);
 
@@ -549,7 +550,8 @@ static void nfp_flower_clean(struct nfp_app *app)
 {
        struct nfp_flower_priv *app_priv = app->priv;
 
-       skb_queue_purge(&app_priv->cmsg_skbs);
+       skb_queue_purge(&app_priv->cmsg_skbs_high);
+       skb_queue_purge(&app_priv->cmsg_skbs_low);
        flush_work(&app_priv->cmsg_work);
 
        nfp_flower_metadata_cleanup(app);
index e030b3c..c67e1b5 100644 (file)
@@ -107,7 +107,10 @@ struct nfp_mtu_conf {
  * @mask_table:                Hash table used to store masks
  * @flow_table:                Hash table used to store flower rules
  * @cmsg_work:         Workqueue for control messages processing
- * @cmsg_skbs:         List of skbs for control message processing
+ * @cmsg_skbs_high:    List of higher priority skbs for control message
+ *                     processing
+ * @cmsg_skbs_low:     List of lower priority skbs for control message
+ *                     processing
  * @nfp_mac_off_list:  List of MAC addresses to offload
  * @nfp_mac_index_list:        List of unique 8-bit indexes for non NFP netdevs
  * @nfp_ipv4_off_list: List of IPv4 addresses to offload
@@ -136,7 +139,8 @@ struct nfp_flower_priv {
        DECLARE_HASHTABLE(mask_table, NFP_FLOWER_MASK_HASH_BITS);
        DECLARE_HASHTABLE(flow_table, NFP_FLOWER_HASH_BITS);
        struct work_struct cmsg_work;
-       struct sk_buff_head cmsg_skbs;
+       struct sk_buff_head cmsg_skbs_high;
+       struct sk_buff_head cmsg_skbs_low;
        struct list_head nfp_mac_off_list;
        struct list_head nfp_mac_index_list;
        struct list_head nfp_ipv4_off_list;
index f7b9581..cb28ac0 100644 (file)
@@ -211,8 +211,11 @@ int nfp_cpp_mutex_lock(struct nfp_cpp_mutex *mutex)
                        break;
 
                err = msleep_interruptible(timeout_ms);
-               if (err != 0)
+               if (err != 0) {
+                       nfp_info(mutex->cpp,
+                                "interrupted waiting for NFP mutex\n");
                        return -ERESTARTSYS;
+               }
 
                if (time_is_before_eq_jiffies(warn_at)) {
                        warn_at = jiffies + NFP_MUTEX_WAIT_NEXT_WARN * HZ;
index 99bb679..2abee0f 100644 (file)
@@ -281,8 +281,7 @@ nfp_nsp_wait_reg(struct nfp_cpp *cpp, u64 *reg, u32 nsp_cpp, u64 addr,
                if ((*reg & mask) == val)
                        return 0;
 
-               if (msleep_interruptible(25))
-                       return -ERESTARTSYS;
+               msleep(25);
 
                if (time_after(start_time, wait_until))
                        return -ETIMEDOUT;
index d339885..5f4e447 100644 (file)
@@ -350,15 +350,16 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
 
        real_dev = priv->real_dev;
 
-       if (!rmnet_is_real_dev_registered(real_dev))
-               return -ENODEV;
-
        if (nla_put_u16(skb, IFLA_RMNET_MUX_ID, priv->mux_id))
                goto nla_put_failure;
 
-       port = rmnet_get_port_rtnl(real_dev);
+       if (rmnet_is_real_dev_registered(real_dev)) {
+               port = rmnet_get_port_rtnl(real_dev);
+               f.flags = port->data_format;
+       } else {
+               f.flags = 0;
+       }
 
-       f.flags = port->data_format;
        f.mask  = ~0;
 
        if (nla_put(skb, IFLA_RMNET_FLAGS, sizeof(f), &f))
index 50daad0..83ce229 100644 (file)
@@ -4776,8 +4776,7 @@ static bool efx_ef10_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
                goto out_unlock;
        }
 
-       if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id,
-                                flow_id, filter_idx)) {
+       if (!rps_may_expire_flow(efx->net_dev, spec->dmaq_id, flow_id, 0)) {
                ret = false;
                goto out_unlock;
        }
@@ -5265,7 +5264,7 @@ static int efx_ef10_filter_insert_addr_list(struct efx_nic *efx,
                ids = vlan->uc;
        }
 
-       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+       filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
 
        /* Insert/renew filters */
        for (i = 0; i < addr_count; i++) {
@@ -5334,7 +5333,7 @@ static int efx_ef10_filter_insert_def(struct efx_nic *efx,
        int rc;
        u16 *id;
 
-       filter_flags = efx_rss_enabled(efx) ? EFX_FILTER_FLAG_RX_RSS : 0;
+       filter_flags = efx_rss_active(&efx->rss_context) ? EFX_FILTER_FLAG_RX_RSS : 0;
 
        efx_filter_init_rx(&spec, EFX_FILTER_PRI_AUTO, filter_flags, 0);
 
index 4a19c7e..7174ef5 100644 (file)
@@ -2912,7 +2912,7 @@ bool efx_farch_filter_rfs_expire_one(struct efx_nic *efx, u32 flow_id,
        if (test_bit(index, table->used_bitmap) &&
            table->spec[index].priority == EFX_FILTER_PRI_HINT &&
            rps_may_expire_flow(efx->net_dev, table->spec[index].dmaq_id,
-                               flow_id, index)) {
+                               flow_id, 0)) {
                efx_farch_filter_table_clear_entry(efx, table, index);
                ret = true;
        }
index 5e379a8..eea3808 100644 (file)
@@ -733,6 +733,27 @@ struct efx_rss_context {
        u32 rx_indir_table[128];
 };
 
+#ifdef CONFIG_RFS_ACCEL
+/**
+ * struct efx_async_filter_insertion - Request to asynchronously insert a filter
+ * @net_dev: Reference to the netdevice
+ * @spec: The filter to insert
+ * @work: Workitem for this request
+ * @rxq_index: Identifies the channel for which this request was made
+ * @flow_id: Identifies the kernel-side flow for which this request was made
+ */
+struct efx_async_filter_insertion {
+       struct net_device *net_dev;
+       struct efx_filter_spec spec;
+       struct work_struct work;
+       u16 rxq_index;
+       u32 flow_id;
+};
+
+/* Maximum number of ARFS workitems that may be in flight on an efx_nic */
+#define EFX_RPS_MAX_IN_FLIGHT  8
+#endif /* CONFIG_RFS_ACCEL */
+
 /**
  * struct efx_nic - an Efx NIC
  * @name: Device name (net device name or bus id before net device registered)
@@ -850,6 +871,8 @@ struct efx_rss_context {
  * @rps_expire_channel: Next channel to check for expiry
  * @rps_expire_index: Next index to check for expiry in
  *     @rps_expire_channel's @rps_flow_id
+ * @rps_slot_map: bitmap of in-flight entries in @rps_slot
+ * @rps_slot: array of ARFS insertion requests for efx_filter_rfs_work()
  * @active_queues: Count of RX and TX queues that haven't been flushed and drained.
  * @rxq_flush_pending: Count of number of receive queues that need to be flushed.
  *     Decremented when the efx_flush_rx_queue() is called.
@@ -1004,6 +1027,8 @@ struct efx_nic {
        struct mutex rps_mutex;
        unsigned int rps_expire_channel;
        unsigned int rps_expire_index;
+       unsigned long rps_slot_map;
+       struct efx_async_filter_insertion rps_slot[EFX_RPS_MAX_IN_FLIGHT];
 #endif
 
        atomic_t active_queues;
index 9568283..9c593c6 100644 (file)
@@ -827,31 +827,16 @@ MODULE_PARM_DESC(rx_refill_threshold,
 
 #ifdef CONFIG_RFS_ACCEL
 
-/**
- * struct efx_async_filter_insertion - Request to asynchronously insert a filter
- * @net_dev: Reference to the netdevice
- * @spec: The filter to insert
- * @work: Workitem for this request
- * @rxq_index: Identifies the channel for which this request was made
- * @flow_id: Identifies the kernel-side flow for which this request was made
- */
-struct efx_async_filter_insertion {
-       struct net_device *net_dev;
-       struct efx_filter_spec spec;
-       struct work_struct work;
-       u16 rxq_index;
-       u32 flow_id;
-};
-
 static void efx_filter_rfs_work(struct work_struct *data)
 {
        struct efx_async_filter_insertion *req = container_of(data, struct efx_async_filter_insertion,
                                                              work);
        struct efx_nic *efx = netdev_priv(req->net_dev);
        struct efx_channel *channel = efx_get_channel(efx, req->rxq_index);
+       int slot_idx = req - efx->rps_slot;
        int rc;
 
-       rc = efx->type->filter_insert(efx, &req->spec, false);
+       rc = efx->type->filter_insert(efx, &req->spec, true);
        if (rc >= 0) {
                /* Remember this so we can check whether to expire the filter
                 * later.
@@ -878,8 +863,8 @@ static void efx_filter_rfs_work(struct work_struct *data)
        }
 
        /* Release references */
+       clear_bit(slot_idx, &efx->rps_slot_map);
        dev_put(req->net_dev);
-       kfree(req);
 }
 
 int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
@@ -888,22 +873,36 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
        struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_async_filter_insertion *req;
        struct flow_keys fk;
+       int slot_idx;
+       int rc;
 
-       if (flow_id == RPS_FLOW_ID_INVALID)
-               return -EINVAL;
+       /* find a free slot */
+       for (slot_idx = 0; slot_idx < EFX_RPS_MAX_IN_FLIGHT; slot_idx++)
+               if (!test_and_set_bit(slot_idx, &efx->rps_slot_map))
+                       break;
+       if (slot_idx >= EFX_RPS_MAX_IN_FLIGHT)
+               return -EBUSY;
 
-       if (!skb_flow_dissect_flow_keys(skb, &fk, 0))
-               return -EPROTONOSUPPORT;
+       if (flow_id == RPS_FLOW_ID_INVALID) {
+               rc = -EINVAL;
+               goto out_clear;
+       }
 
-       if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6))
-               return -EPROTONOSUPPORT;
-       if (fk.control.flags & FLOW_DIS_IS_FRAGMENT)
-               return -EPROTONOSUPPORT;
+       if (!skb_flow_dissect_flow_keys(skb, &fk, 0)) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
 
-       req = kmalloc(sizeof(*req), GFP_ATOMIC);
-       if (!req)
-               return -ENOMEM;
+       if (fk.basic.n_proto != htons(ETH_P_IP) && fk.basic.n_proto != htons(ETH_P_IPV6)) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
+       if (fk.control.flags & FLOW_DIS_IS_FRAGMENT) {
+               rc = -EPROTONOSUPPORT;
+               goto out_clear;
+       }
 
+       req = efx->rps_slot + slot_idx;
        efx_filter_init_rx(&req->spec, EFX_FILTER_PRI_HINT,
                           efx->rx_scatter ? EFX_FILTER_FLAG_RX_SCATTER : 0,
                           rxq_index);
@@ -933,6 +932,9 @@ int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb,
        req->flow_id = flow_id;
        schedule_work(&req->work);
        return 0;
+out_clear:
+       clear_bit(slot_idx, &efx->rps_slot_map);
+       return rc;
 }
 
 bool __efx_filter_rfs_expire(struct efx_nic *efx, unsigned int quota)
index c7bff59..dedd406 100644 (file)
@@ -347,7 +347,7 @@ enum power_event {
 #define MTL_RX_OVERFLOW_INT            BIT(16)
 
 /* Default operating mode of the MAC */
-#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | GMAC_CONFIG_ACS | \
+#define GMAC_CORE_INIT (GMAC_CONFIG_JD | GMAC_CONFIG_PS | \
                        GMAC_CONFIG_BE | GMAC_CONFIG_DCRS)
 
 /* To dump the core regs excluding  the Address Registers */
index a3af92e..517b1f6 100644 (file)
@@ -31,13 +31,6 @@ static void dwmac4_core_init(struct mac_device_info *hw,
 
        value |= GMAC_CORE_INIT;
 
-       /* Clear ACS bit because Ethernet switch tagging formats such as
-        * Broadcom tags can look like invalid LLC/SNAP packets and cause the
-        * hardware to truncate packets on reception.
-        */
-       if (netdev_uses_dsa(dev))
-               value &= ~GMAC_CONFIG_ACS;
-
        if (mtu > 1500)
                value |= GMAC_CONFIG_2K;
        if (mtu > 2000)
index 9a16931..b65e2d1 100644 (file)
@@ -3495,8 +3495,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 
                        /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3
                         * Type frames (LLC/LLC-SNAP)
+                        *
+                        * llc_snap is never checked in GMAC >= 4, so this ACS
+                        * feature is always disabled and packets need to be
+                        * stripped manually.
                         */
-                       if (unlikely(status != llc_snap))
+                       if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) ||
+                           unlikely(status != llc_snap))
                                frame_len -= ETH_FCS_LEN;
 
                        if (netif_msg_rx_status(priv)) {
index 9cbb0c8..7de88b3 100644 (file)
@@ -3277,7 +3277,7 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 
        err = netdev_upper_dev_link(real_dev, dev, extack);
        if (err < 0)
-               goto put_dev;
+               goto unregister;
 
        /* need to be already registered so that ->init has run and
         * the MAC addr is set
@@ -3316,8 +3316,7 @@ del_dev:
        macsec_del_dev(macsec);
 unlink:
        netdev_upper_dev_unlink(real_dev, dev);
-put_dev:
-       dev_put(real_dev);
+unregister:
        unregister_netdevice(dev);
        return err;
 }
index 0f293ef..a97ac8c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/microchipphy.h>
+#include <linux/delay.h>
 
 #define DRIVER_AUTHOR  "WOOJUNG HUH <woojung.huh@microchip.com>"
 #define DRIVER_DESC    "Microchip LAN88XX PHY driver"
@@ -30,6 +31,16 @@ struct lan88xx_priv {
        __u32   wolopts;
 };
 
+static int lan88xx_read_page(struct phy_device *phydev)
+{
+       return __phy_read(phydev, LAN88XX_EXT_PAGE_ACCESS);
+}
+
+static int lan88xx_write_page(struct phy_device *phydev, int page)
+{
+       return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page);
+}
+
 static int lan88xx_phy_config_intr(struct phy_device *phydev)
 {
        int rc;
@@ -66,6 +77,150 @@ static int lan88xx_suspend(struct phy_device *phydev)
        return 0;
 }
 
+static int lan88xx_TR_reg_set(struct phy_device *phydev, u16 regaddr,
+                             u32 data)
+{
+       int val, save_page, ret = 0;
+       u16 buf;
+
+       /* Save current page */
+       save_page = phy_save_page(phydev);
+       if (save_page < 0) {
+               pr_warn("Failed to get current page\n");
+               goto err;
+       }
+
+       /* Switch to TR page */
+       lan88xx_write_page(phydev, LAN88XX_EXT_PAGE_ACCESS_TR);
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_LOW_DATA,
+                         (data & 0xFFFF));
+       if (ret < 0) {
+               pr_warn("Failed to write TR low data\n");
+               goto err;
+       }
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_HIGH_DATA,
+                         (data & 0x00FF0000) >> 16);
+       if (ret < 0) {
+               pr_warn("Failed to write TR high data\n");
+               goto err;
+       }
+
+       /* Config control bits [15:13] of register */
+       buf = (regaddr & ~(0x3 << 13));/* Clr [14:13] to write data in reg */
+       buf |= 0x8000; /* Set [15] to Packet transmit */
+
+       ret = __phy_write(phydev, LAN88XX_EXT_PAGE_TR_CR, buf);
+       if (ret < 0) {
+               pr_warn("Failed to write data in reg\n");
+               goto err;
+       }
+
+       usleep_range(1000, 2000);/* Wait for Data to be written */
+       val = __phy_read(phydev, LAN88XX_EXT_PAGE_TR_CR);
+       if (!(val & 0x8000))
+               pr_warn("TR Register[0x%X] configuration failed\n", regaddr);
+err:
+       return phy_restore_page(phydev, save_page, ret);
+}
+
+static void lan88xx_config_TR_regs(struct phy_device *phydev)
+{
+       int err;
+
+       /* Get access to Channel 0x1, Node 0xF , Register 0x01.
+        * Write 24-bit value 0x12B00A to register. Setting MrvlTrFix1000Kf,
+        * MrvlTrFix1000Kp, MasterEnableTR bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0F82, 0x12B00A);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0F82]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x06.
+        * Write 24-bit value 0xD2C46F to register. Setting SSTrKf1000Slv,
+        * SSTrKp1000Mas bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x168C, 0xD2C46F);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x168C]\n");
+
+       /* Get access to Channel b'10, Node b'1111, Register 0x11.
+        * Write 24-bit value 0x620 to register. Setting rem_upd_done_thresh
+        * bits
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x17A2, 0x620);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x17A2]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x10.
+        * Write 24-bit value 0xEEFFDD to register. Setting
+        * eee_TrKp1Long_1000, eee_TrKp2Long_1000, eee_TrKp3Long_1000,
+        * eee_TrKp1Short_1000,eee_TrKp2Short_1000, eee_TrKp3Short_1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A0, 0xEEFFDD);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A0]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x13.
+        * Write 24-bit value 0x071448 to register. Setting
+        * slv_lpi_tr_tmr_val1, slv_lpi_tr_tmr_val2 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A6, 0x071448);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A6]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x12.
+        * Write 24-bit value 0x13132F to register. Setting
+        * slv_sigdet_timer_val1, slv_sigdet_timer_val2 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A4, 0x13132F);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A4]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x14.
+        * Write 24-bit value 0x0 to register. Setting eee_3level_delay,
+        * eee_TrKf_freeze_delay bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x16A8, 0x0);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x16A8]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x34.
+        * Write 24-bit value 0x91B06C to register. Setting
+        * FastMseSearchThreshLong1000, FastMseSearchThreshShort1000,
+        * FastMseSearchUpdGain1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FE8, 0x91B06C);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FE8]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x3E.
+        * Write 24-bit value 0xC0A028 to register. Setting
+        * FastMseKp2ThreshLong1000, FastMseKp2ThreshShort1000,
+        * FastMseKp2UpdGain1000, FastMseKp2ExitEn1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FFC, 0xC0A028);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FFC]\n");
+
+       /* Get access to Channel b'01, Node b'1111, Register 0x35.
+        * Write 24-bit value 0x041600 to register. Setting
+        * FastMseSearchPhShNum1000, FastMseSearchClksPerPh1000,
+        * FastMsePhChangeDelay1000 bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x0FEA, 0x041600);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x0FEA]\n");
+
+       /* Get access to Channel b'10, Node b'1101, Register 0x03.
+        * Write 24-bit value 0x000004 to register. Setting TrFreeze bits.
+        */
+       err = lan88xx_TR_reg_set(phydev, 0x1686, 0x000004);
+       if (err < 0)
+               pr_warn("Failed to Set Register[0x1686]\n");
+}
+
 static int lan88xx_probe(struct phy_device *phydev)
 {
        struct device *dev = &phydev->mdio.dev;
@@ -132,6 +287,25 @@ static void lan88xx_set_mdix(struct phy_device *phydev)
        phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, LAN88XX_EXT_PAGE_SPACE_0);
 }
 
+static int lan88xx_config_init(struct phy_device *phydev)
+{
+       int val;
+
+       genphy_config_init(phydev);
+       /*Zerodetect delay enable */
+       val = phy_read_mmd(phydev, MDIO_MMD_PCS,
+                          PHY_ARDENNES_MMD_DEV_3_PHY_CFG);
+       val |= PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_;
+
+       phy_write_mmd(phydev, MDIO_MMD_PCS, PHY_ARDENNES_MMD_DEV_3_PHY_CFG,
+                     val);
+
+       /* Config DSP registers */
+       lan88xx_config_TR_regs(phydev);
+
+       return 0;
+}
+
 static int lan88xx_config_aneg(struct phy_device *phydev)
 {
        lan88xx_set_mdix(phydev);
@@ -151,7 +325,7 @@ static struct phy_driver microchip_phy_driver[] = {
        .probe          = lan88xx_probe,
        .remove         = lan88xx_remove,
 
-       .config_init    = genphy_config_init,
+       .config_init    = lan88xx_config_init,
        .config_aneg    = lan88xx_config_aneg,
 
        .ack_interrupt  = lan88xx_phy_ack_interrupt,
@@ -160,6 +334,8 @@ static struct phy_driver microchip_phy_driver[] = {
        .suspend        = lan88xx_suspend,
        .resume         = genphy_resume,
        .set_wol        = lan88xx_set_wol,
+       .read_page      = lan88xx_read_page,
+       .write_page     = lan88xx_write_page,
 } };
 
 module_phy_driver(microchip_phy_driver);
index a6c6ce1..acbe849 100644 (file)
@@ -261,6 +261,17 @@ static void __team_option_inst_mark_removed_port(struct team *team,
        }
 }
 
+static bool __team_option_inst_tmp_find(const struct list_head *opts,
+                                       const struct team_option_inst *needle)
+{
+       struct team_option_inst *opt_inst;
+
+       list_for_each_entry(opt_inst, opts, tmp_list)
+               if (opt_inst == needle)
+                       return true;
+       return false;
+}
+
 static int __team_options_register(struct team *team,
                                   const struct team_option *option,
                                   size_t option_count)
@@ -2568,6 +2579,14 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
                        if (err)
                                goto team_put;
                        opt_inst->changed = true;
+
+                       /* dumb/evil user-space can send us duplicate opt,
+                        * keep only the last one
+                        */
+                       if (__team_option_inst_tmp_find(&opt_inst_list,
+                                                       opt_inst))
+                               continue;
+
                        list_add(&opt_inst->tmp_list, &opt_inst_list);
                }
                if (!opt_found) {
index 28583aa..ef33950 100644 (file)
@@ -1102,12 +1102,7 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                goto drop;
 
        len = run_ebpf_filter(tun, skb, len);
-
-       /* Trim extra bytes since we may insert vlan proto & TCI
-        * in tun_put_user().
-        */
-       len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0;
-       if (len <= 0 || pskb_trim(skb, len))
+       if (len == 0 || pskb_trim(skb, len))
                goto drop;
 
        if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC)))
index ca066b7..c853e74 100644 (file)
@@ -1107,6 +1107,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1435, 0xd181, 3)},    /* Wistron NeWeb D18Q1 */
        {QMI_FIXED_INTF(0x1435, 0xd181, 4)},    /* Wistron NeWeb D18Q1 */
        {QMI_FIXED_INTF(0x1435, 0xd181, 5)},    /* Wistron NeWeb D18Q1 */
+       {QMI_FIXED_INTF(0x1435, 0xd191, 4)},    /* Wistron NeWeb D19Q1 */
        {QMI_FIXED_INTF(0x16d8, 0x6003, 0)},    /* CMOTech 6003 */
        {QMI_FIXED_INTF(0x16d8, 0x6007, 0)},    /* CMOTech CHE-628S */
        {QMI_FIXED_INTF(0x16d8, 0x6008, 0)},    /* CMOTech CMU-301 */
index 7b187ec..770422e 100644 (file)
@@ -147,6 +147,17 @@ struct receive_queue {
        struct xdp_rxq_info xdp_rxq;
 };
 
+/* Control VQ buffers: protected by the rtnl lock */
+struct control_buf {
+       struct virtio_net_ctrl_hdr hdr;
+       virtio_net_ctrl_ack status;
+       struct virtio_net_ctrl_mq mq;
+       u8 promisc;
+       u8 allmulti;
+       __virtio16 vid;
+       __virtio64 offloads;
+};
+
 struct virtnet_info {
        struct virtio_device *vdev;
        struct virtqueue *cvq;
@@ -192,14 +203,7 @@ struct virtnet_info {
        struct hlist_node node;
        struct hlist_node node_dead;
 
-       /* Control VQ buffers: protected by the rtnl lock */
-       struct virtio_net_ctrl_hdr ctrl_hdr;
-       virtio_net_ctrl_ack ctrl_status;
-       struct virtio_net_ctrl_mq ctrl_mq;
-       u8 ctrl_promisc;
-       u8 ctrl_allmulti;
-       u16 ctrl_vid;
-       u64 ctrl_offloads;
+       struct control_buf *ctrl;
 
        /* Ethtool settings */
        u8 duplex;
@@ -1269,7 +1273,9 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 {
        struct receive_queue *rq =
                container_of(napi, struct receive_queue, napi);
-       unsigned int received;
+       struct virtnet_info *vi = rq->vq->vdev->priv;
+       struct send_queue *sq;
+       unsigned int received, qp;
        bool xdp_xmit = false;
 
        virtnet_poll_cleantx(rq);
@@ -1280,8 +1286,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
        if (received < budget)
                virtqueue_napi_complete(napi, rq->vq, received);
 
-       if (xdp_xmit)
+       if (xdp_xmit) {
+               qp = vi->curr_queue_pairs - vi->xdp_queue_pairs +
+                    smp_processor_id();
+               sq = &vi->sq[qp];
+               virtqueue_kick(sq->vq);
                xdp_do_flush_map();
+       }
 
        return received;
 }
@@ -1454,25 +1465,25 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
        /* Caller should know better */
        BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
 
-       vi->ctrl_status = ~0;
-       vi->ctrl_hdr.class = class;
-       vi->ctrl_hdr.cmd = cmd;
+       vi->ctrl->status = ~0;
+       vi->ctrl->hdr.class = class;
+       vi->ctrl->hdr.cmd = cmd;
        /* Add header */
-       sg_init_one(&hdr, &vi->ctrl_hdr, sizeof(vi->ctrl_hdr));
+       sg_init_one(&hdr, &vi->ctrl->hdr, sizeof(vi->ctrl->hdr));
        sgs[out_num++] = &hdr;
 
        if (out)
                sgs[out_num++] = out;
 
        /* Add return status. */
-       sg_init_one(&stat, &vi->ctrl_status, sizeof(vi->ctrl_status));
+       sg_init_one(&stat, &vi->ctrl->status, sizeof(vi->ctrl->status));
        sgs[out_num] = &stat;
 
        BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
        virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
 
        if (unlikely(!virtqueue_kick(vi->cvq)))
-               return vi->ctrl_status == VIRTIO_NET_OK;
+               return vi->ctrl->status == VIRTIO_NET_OK;
 
        /* Spin for a response, the kick causes an ioport write, trapping
         * into the hypervisor, so the request should be handled immediately.
@@ -1481,7 +1492,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
               !virtqueue_is_broken(vi->cvq))
                cpu_relax();
 
-       return vi->ctrl_status == VIRTIO_NET_OK;
+       return vi->ctrl->status == VIRTIO_NET_OK;
 }
 
 static int virtnet_set_mac_address(struct net_device *dev, void *p)
@@ -1593,8 +1604,8 @@ static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs)
        if (!vi->has_cvq || !virtio_has_feature(vi->vdev, VIRTIO_NET_F_MQ))
                return 0;
 
-       vi->ctrl_mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
-       sg_init_one(&sg, &vi->ctrl_mq, sizeof(vi->ctrl_mq));
+       vi->ctrl->mq.virtqueue_pairs = cpu_to_virtio16(vi->vdev, queue_pairs);
+       sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ,
                                  VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) {
@@ -1653,22 +1664,22 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
                return;
 
-       vi->ctrl_promisc = ((dev->flags & IFF_PROMISC) != 0);
-       vi->ctrl_allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+       vi->ctrl->promisc = ((dev->flags & IFF_PROMISC) != 0);
+       vi->ctrl->allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
 
-       sg_init_one(sg, &vi->ctrl_promisc, sizeof(vi->ctrl_promisc));
+       sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_PROMISC, sg))
                dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
-                        vi->ctrl_promisc ? "en" : "dis");
+                        vi->ctrl->promisc ? "en" : "dis");
 
-       sg_init_one(sg, &vi->ctrl_allmulti, sizeof(vi->ctrl_allmulti));
+       sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
                                  VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
                dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
-                        vi->ctrl_allmulti ? "en" : "dis");
+                        vi->ctrl->allmulti ? "en" : "dis");
 
        uc_count = netdev_uc_count(dev);
        mc_count = netdev_mc_count(dev);
@@ -1714,8 +1725,8 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev,
        struct virtnet_info *vi = netdev_priv(dev);
        struct scatterlist sg;
 
-       vi->ctrl_vid = vid;
-       sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
+       vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
+       sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
                                  VIRTIO_NET_CTRL_VLAN_ADD, &sg))
@@ -1729,8 +1740,8 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev,
        struct virtnet_info *vi = netdev_priv(dev);
        struct scatterlist sg;
 
-       vi->ctrl_vid = vid;
-       sg_init_one(&sg, &vi->ctrl_vid, sizeof(vi->ctrl_vid));
+       vi->ctrl->vid = cpu_to_virtio16(vi->vdev, vid);
+       sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
                                  VIRTIO_NET_CTRL_VLAN_DEL, &sg))
@@ -2126,9 +2137,9 @@ static int virtnet_restore_up(struct virtio_device *vdev)
 static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads)
 {
        struct scatterlist sg;
-       vi->ctrl_offloads = cpu_to_virtio64(vi->vdev, offloads);
+       vi->ctrl->offloads = cpu_to_virtio64(vi->vdev, offloads);
 
-       sg_init_one(&sg, &vi->ctrl_offloads, sizeof(vi->ctrl_offloads));
+       sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads));
 
        if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS,
                                  VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) {
@@ -2351,6 +2362,7 @@ static void virtnet_free_queues(struct virtnet_info *vi)
 
        kfree(vi->rq);
        kfree(vi->sq);
+       kfree(vi->ctrl);
 }
 
 static void _free_receive_bufs(struct virtnet_info *vi)
@@ -2543,6 +2555,9 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
 {
        int i;
 
+       vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL);
+       if (!vi->ctrl)
+               goto err_ctrl;
        vi->sq = kzalloc(sizeof(*vi->sq) * vi->max_queue_pairs, GFP_KERNEL);
        if (!vi->sq)
                goto err_sq;
@@ -2571,6 +2586,8 @@ static int virtnet_alloc_queues(struct virtnet_info *vi)
 err_rq:
        kfree(vi->sq);
 err_sq:
+       kfree(vi->ctrl);
+err_ctrl:
        return -ENOMEM;
 }
 
index e04937f..9ebe2a6 100644 (file)
@@ -1218,6 +1218,7 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
        union {
                void *ptr;
                struct ethhdr *eth;
+               struct vlan_ethhdr *veth;
                struct iphdr *ipv4;
                struct ipv6hdr *ipv6;
                struct tcphdr *tcp;
@@ -1228,16 +1229,24 @@ vmxnet3_get_hdr_len(struct vmxnet3_adapter *adapter, struct sk_buff *skb,
        if (unlikely(sizeof(struct iphdr) + sizeof(struct tcphdr) > maplen))
                return 0;
 
+       if (skb->protocol == cpu_to_be16(ETH_P_8021Q) ||
+           skb->protocol == cpu_to_be16(ETH_P_8021AD))
+               hlen = sizeof(struct vlan_ethhdr);
+       else
+               hlen = sizeof(struct ethhdr);
+
        hdr.eth = eth_hdr(skb);
        if (gdesc->rcd.v4) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IP) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IP));
+               hdr.ptr += hlen;
                BUG_ON(hdr.ipv4->protocol != IPPROTO_TCP);
                hlen = hdr.ipv4->ihl << 2;
                hdr.ptr += hdr.ipv4->ihl << 2;
        } else if (gdesc->rcd.v6) {
-               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6));
-               hdr.ptr += sizeof(struct ethhdr);
+               BUG_ON(hdr.eth->h_proto != htons(ETH_P_IPV6) &&
+                      hdr.veth->h_vlan_encapsulated_proto != htons(ETH_P_IPV6));
+               hdr.ptr += hlen;
                /* Use an estimated value, since we also need to handle
                 * TSO case.
                 */
index 59ec340..a332646 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.4.13.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.4.14.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01040d00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01040e00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 8599718..9d36473 100644 (file)
@@ -103,8 +103,7 @@ config NVDIMM_DAX
          Select Y if unsure
 
 config OF_PMEM
-       # FIXME: make tristate once OF_NUMA dependency removed
-       bool "Device-tree support for persistent memory regions"
+       tristate "Device-tree support for persistent memory regions"
        depends on OF
        default LIBNVDIMM
        help
index e00d455..8d348b2 100644 (file)
@@ -88,9 +88,9 @@ int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd)
 int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
 {
        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
+       int rc = validate_dimm(ndd), cmd_rc = 0;
        struct nd_cmd_get_config_data_hdr *cmd;
        struct nvdimm_bus_descriptor *nd_desc;
-       int rc = validate_dimm(ndd);
        u32 max_cmd_size, config_size;
        size_t offset;
 
@@ -124,9 +124,11 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
                cmd->in_offset = offset;
                rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
                                ND_CMD_GET_CONFIG_DATA, cmd,
-                               cmd->in_length + sizeof(*cmd), NULL);
-               if (rc || cmd->status) {
-                       rc = -ENXIO;
+                               cmd->in_length + sizeof(*cmd), &cmd_rc);
+               if (rc < 0)
+                       break;
+               if (cmd_rc < 0) {
+                       rc = cmd_rc;
                        break;
                }
                memcpy(ndd->data + offset, cmd->out_buf, cmd->in_length);
@@ -140,9 +142,9 @@ int nvdimm_init_config_data(struct nvdimm_drvdata *ndd)
 int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
                void *buf, size_t len)
 {
-       int rc = validate_dimm(ndd);
        size_t max_cmd_size, buf_offset;
        struct nd_cmd_set_config_hdr *cmd;
+       int rc = validate_dimm(ndd), cmd_rc = 0;
        struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(ndd->dev);
        struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
 
@@ -164,7 +166,6 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
        for (buf_offset = 0; len; len -= cmd->in_length,
                        buf_offset += cmd->in_length) {
                size_t cmd_size;
-               u32 *status;
 
                cmd->in_offset = offset + buf_offset;
                cmd->in_length = min(max_cmd_size, len);
@@ -172,12 +173,13 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
 
                /* status is output in the last 4-bytes of the command buffer */
                cmd_size = sizeof(*cmd) + cmd->in_length + sizeof(u32);
-               status = ((void *) cmd) + cmd_size - sizeof(u32);
 
                rc = nd_desc->ndctl(nd_desc, to_nvdimm(ndd->dev),
-                               ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, NULL);
-               if (rc || *status) {
-                       rc = rc ? rc : -ENXIO;
+                               ND_CMD_SET_CONFIG_DATA, cmd, cmd_size, &cmd_rc);
+               if (rc < 0)
+                       break;
+               if (cmd_rc < 0) {
+                       rc = cmd_rc;
                        break;
                }
        }
index 85013ba..0a70183 100644 (file)
@@ -67,7 +67,7 @@ static int of_pmem_region_probe(struct platform_device *pdev)
                 */
                memset(&ndr_desc, 0, sizeof(ndr_desc));
                ndr_desc.attr_groups = region_attr_groups;
-               ndr_desc.numa_node = of_node_to_nid(np);
+               ndr_desc.numa_node = dev_to_node(&pdev->dev);
                ndr_desc.res = &pdev->resource[i];
                ndr_desc.of_node = np;
                set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
index 9d27016..0434ab7 100644 (file)
@@ -740,10 +740,7 @@ static int do_dma_request(struct mport_dma_req *req,
        tx->callback = dma_xfer_callback;
        tx->callback_param = req;
 
-       req->dmach = chan;
-       req->sync = sync;
        req->status = DMA_IN_PROGRESS;
-       init_completion(&req->req_comp);
        kref_get(&req->refcount);
 
        cookie = dmaengine_submit(tx);
@@ -831,13 +828,20 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode,
        if (!req)
                return -ENOMEM;
 
-       kref_init(&req->refcount);
-
        ret = get_dma_channel(priv);
        if (ret) {
                kfree(req);
                return ret;
        }
+       chan = priv->dmach;
+
+       kref_init(&req->refcount);
+       init_completion(&req->req_comp);
+       req->dir = dir;
+       req->filp = filp;
+       req->priv = priv;
+       req->dmach = chan;
+       req->sync = sync;
 
        /*
         * If parameter loc_addr != NULL, we are transferring data from/to
@@ -925,11 +929,6 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode,
                                xfer->offset, xfer->length);
        }
 
-       req->dir = dir;
-       req->filp = filp;
-       req->priv = priv;
-       chan = priv->dmach;
-
        nents = dma_map_sg(chan->device->dev,
                           req->sgt.sgl, req->sgt.nents, dir);
        if (nents == 0) {
index f035c2f..131f198 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/vtoc.h>
-#include <asm/diag.h>
 
 #include "dasd_int.h"
 #include "dasd_diag.h"
index 5f8d9ea..eceba38 100644 (file)
@@ -18,7 +18,7 @@ int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
  * Used to keep track of the size of the event masks. Qemu until version 2.11
  * only supports 4 and needs a workaround.
  */
-bool sclp_mask_compat_mode;
+bool sclp_mask_compat_mode __section(.data);
 
 void sclp_early_wait_irq(void)
 {
index 50a3138..2ad6f12 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/list.h>
 #include <linux/hash.h>
 #include <linux/hashtable.h>
-#include <linux/string.h>
 #include <asm/setup.h>
 #include "qeth_core.h"
 #include "qeth_l2.h"
index 3b0c8b8..066b5c3 100644 (file)
@@ -176,7 +176,7 @@ static struct device_driver smsg_driver = {
 
 static void __exit smsg_exit(void)
 {
-       cpcmd("SET SMSG IUCV", NULL, 0, NULL);
+       cpcmd("SET SMSG OFF", NULL, 0, NULL);
        device_unregister(smsg_dev);
        iucv_unregister(&smsg_handler, 1);
        driver_unregister(&smsg_driver);
index a5b8eb2..1abe4d0 100644 (file)
@@ -55,6 +55,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
 #define   WDT_CTRL_WDT_INTR            BIT(2)
 #define   WDT_CTRL_RESET_SYSTEM                BIT(1)
 #define   WDT_CTRL_ENABLE              BIT(0)
+#define WDT_TIMEOUT_STATUS     0x10
+#define   WDT_TIMEOUT_STATUS_BOOT_SECONDARY    BIT(1)
 
 /*
  * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
@@ -192,6 +194,7 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
        struct device_node *np;
        const char *reset_type;
        u32 duration;
+       u32 status;
        int ret;
 
        wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
@@ -307,6 +310,10 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
                writel(duration - 1, wdt->base + WDT_RESET_WIDTH);
        }
 
+       status = readl(wdt->base + WDT_TIMEOUT_STATUS);
+       if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
+               wdt->wdd.bootstatus = WDIOF_CARDRESET;
+
        ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
        if (ret) {
                dev_err(&pdev->dev, "failed to register\n");
index 6b8c6dd..514db5c 100644 (file)
@@ -121,7 +121,8 @@ static int rwdt_restart(struct watchdog_device *wdev, unsigned long action,
 }
 
 static const struct watchdog_info rwdt_ident = {
-       .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+       .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
+               WDIOF_CARDRESET,
        .identity = "Renesas WDT Watchdog",
 };
 
@@ -197,9 +198,10 @@ static int rwdt_probe(struct platform_device *pdev)
                return PTR_ERR(clk);
 
        pm_runtime_enable(&pdev->dev);
-
        pm_runtime_get_sync(&pdev->dev);
        priv->clk_rate = clk_get_rate(clk);
+       priv->wdev.bootstatus = (readb_relaxed(priv->base + RWTCSRA) &
+                               RWTCSRA_WOVF) ? WDIOF_CARDRESET : 0;
        pm_runtime_put(&pdev->dev);
 
        if (!priv->clk_rate) {
index 43d0cbb..814cdf5 100644 (file)
@@ -299,7 +299,7 @@ static long sch311x_wdt_ioctl(struct file *file, unsigned int cmd,
                if (sch311x_wdt_set_heartbeat(new_timeout))
                        return -EINVAL;
                sch311x_wdt_keepalive();
-               /* Fall */
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
        default:
index 20e2bba..672b61a 100644 (file)
@@ -427,7 +427,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        return -EINVAL;
 
                wdt_keepalive();
-               /* Fall */
+               /* Fall through */
 
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, uarg.i);
index db0da7e..93c5b61 100644 (file)
@@ -178,7 +178,7 @@ static long wafwdt_ioctl(struct file *file, unsigned int cmd,
                timeout = new_timeout;
                wafwdt_stop();
                wafwdt_start();
-               /* Fall */
+               /* Fall through */
        case WDIOC_GETTIMEOUT:
                return put_user(timeout, p);
 
index 89d9744..ed593d1 100644 (file)
@@ -95,7 +95,7 @@ int xen_pcibk_config_quirks_init(struct pci_dev *dev)
        struct xen_pcibk_config_quirk *quirk;
        int ret = 0;
 
-       quirk = kzalloc(sizeof(*quirk), GFP_ATOMIC);
+       quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
        if (!quirk) {
                ret = -ENOMEM;
                goto out;
index 9e480fd..59661db 100644 (file)
@@ -71,7 +71,7 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
 
        dev_dbg(&dev->dev, "pcistub_device_alloc\n");
 
-       psdev = kzalloc(sizeof(*psdev), GFP_ATOMIC);
+       psdev = kzalloc(sizeof(*psdev), GFP_KERNEL);
        if (!psdev)
                return NULL;
 
@@ -364,7 +364,7 @@ static int pcistub_init_device(struct pci_dev *dev)
         * here and then to call kfree(pci_get_drvdata(psdev->dev)).
         */
        dev_data = kzalloc(sizeof(*dev_data) +  strlen(DRV_NAME "[]")
-                               + strlen(pci_name(dev)) + 1, GFP_ATOMIC);
+                               + strlen(pci_name(dev)) + 1, GFP_KERNEL);
        if (!dev_data) {
                err = -ENOMEM;
                goto out;
@@ -577,7 +577,7 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
                }
 
                if (!match) {
-                       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_ATOMIC);
+                       pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
                        if (!pci_dev_id) {
                                err = -ENOMEM;
                                goto out;
@@ -1149,7 +1149,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func,
        }
        dev = psdev->dev;
 
-       field = kzalloc(sizeof(*field), GFP_ATOMIC);
+       field = kzalloc(sizeof(*field), GFP_KERNEL);
        if (!field) {
                err = -ENOMEM;
                goto out;
index 0d6d926..c3e2010 100644 (file)
@@ -403,7 +403,7 @@ static int xenbus_command_reply(struct xenbus_file_priv *u,
 {
        struct {
                struct xsd_sockmsg hdr;
-               const char body[16];
+               char body[16];
        } msg;
        int rc;
 
@@ -412,6 +412,7 @@ static int xenbus_command_reply(struct xenbus_file_priv *u,
        msg.hdr.len = strlen(reply) + 1;
        if (msg.hdr.len > sizeof(msg.body))
                return -E2BIG;
+       memcpy(&msg.body, reply, msg.hdr.len);
 
        mutex_lock(&u->reply_mutex);
        rc = queue_reply(&u->read_buffers, &msg, sizeof(msg.hdr) + msg.hdr.len);
index e23be63..629c749 100644 (file)
@@ -428,8 +428,15 @@ static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
                }
                write_sequnlock(&net->fs_lock);
 
-               if (deleted)
+               if (deleted) {
+                       write_seqlock(&net->fs_addr_lock);
+                       if (!hlist_unhashed(&server->addr4_link))
+                               hlist_del_rcu(&server->addr4_link);
+                       if (!hlist_unhashed(&server->addr6_link))
+                               hlist_del_rcu(&server->addr6_link);
+                       write_sequnlock(&net->fs_addr_lock);
                        afs_destroy_server(net, server);
+               }
        }
 }
 
index 82e8f6e..b12e37f 100644 (file)
@@ -749,7 +749,7 @@ static int autofs4_dir_mkdir(struct inode *dir,
 
        autofs4_del_active(dentry);
 
-       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | 0555);
+       inode = autofs4_get_inode(dir->i_sb, S_IFDIR | mode);
        if (!inode)
                return -ENOMEM;
        d_add(dentry, inode);
index 41e0418..4ad6f66 100644 (file)
@@ -377,10 +377,10 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
        } else
                map_addr = vm_mmap(filep, addr, size, prot, type, off);
 
-       if ((type & MAP_FIXED_NOREPLACE) && BAD_ADDR(map_addr))
-               pr_info("%d (%s): Uhuuh, elf segment at %p requested but the memory is mapped already\n",
-                               task_pid_nr(current), current->comm,
-                               (void *)addr);
+       if ((type & MAP_FIXED_NOREPLACE) &&
+           PTR_ERR((void *)map_addr) == -EEXIST)
+               pr_info("%d (%s): Uhuuh, elf segment at %px requested but the memory is mapped already\n",
+                       task_pid_nr(current), current->comm, (void *)addr);
 
        return(map_addr);
 }
index 5474ef1..2771cc5 100644 (file)
@@ -459,6 +459,25 @@ struct btrfs_block_rsv {
        unsigned short full;
        unsigned short type;
        unsigned short failfast;
+
+       /*
+        * Qgroup equivalent for @size @reserved
+        *
+        * Unlike normal @size/@reserved for inode rsv, qgroup doesn't care
+        * about things like csum size nor how many tree blocks it will need to
+        * reserve.
+        *
+        * Qgroup cares more about net change of the extent usage.
+        *
+        * So for one newly inserted file extent, in worst case it will cause
+        * leaf split and level increase, nodesize for each file extent is
+        * already too much.
+        *
+        * In short, qgroup_size/reserved is the upper limit of possible needed
+        * qgroup metadata reservation.
+        */
+       u64 qgroup_rsv_size;
+       u64 qgroup_rsv_reserved;
 };
 
 /*
@@ -714,6 +733,12 @@ struct btrfs_delayed_root;
  */
 #define BTRFS_FS_EXCL_OP                       16
 
+/*
+ * To info transaction_kthread we need an immediate commit so it doesn't
+ * need to wait for commit_interval
+ */
+#define BTRFS_FS_NEED_ASYNC_COMMIT             17
+
 struct btrfs_fs_info {
        u8 fsid[BTRFS_FSID_SIZE];
        u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
index 06ec8ab..a8d492d 100644 (file)
@@ -556,6 +556,12 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
        dst_rsv = &fs_info->delayed_block_rsv;
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
+
+       /*
+        * Here we migrate space rsv from transaction rsv, since have already
+        * reserved space when starting a transaction.  So no need to reserve
+        * qgroup space here.
+        */
        ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
        if (!ret) {
                trace_btrfs_space_reservation(fs_info, "delayed_item",
@@ -577,7 +583,10 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
                return;
 
        rsv = &fs_info->delayed_block_rsv;
-       btrfs_qgroup_convert_reserved_meta(root, item->bytes_reserved);
+       /*
+        * Check btrfs_delayed_item_reserve_metadata() to see why we don't need
+        * to release/reserve qgroup space.
+        */
        trace_btrfs_space_reservation(fs_info, "delayed_item",
                                      item->key.objectid, item->bytes_reserved,
                                      0);
@@ -602,9 +611,6 @@ static int btrfs_delayed_inode_reserve_metadata(
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
 
-       ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
-       if (ret < 0)
-               return ret;
        /*
         * btrfs_dirty_inode will update the inode under btrfs_join_transaction
         * which doesn't reserve space for speed.  This is a problem since we
@@ -616,6 +622,10 @@ static int btrfs_delayed_inode_reserve_metadata(
         */
        if (!src_rsv || (!trans->bytes_reserved &&
                         src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
+               ret = btrfs_qgroup_reserve_meta_prealloc(root,
+                               fs_info->nodesize, true);
+               if (ret < 0)
+                       return ret;
                ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
                                          BTRFS_RESERVE_NO_FLUSH);
                /*
@@ -634,6 +644,8 @@ static int btrfs_delayed_inode_reserve_metadata(
                                                      "delayed_inode",
                                                      btrfs_ino(inode),
                                                      num_bytes, 1);
+               } else {
+                       btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize);
                }
                return ret;
        }
index 9e98295..e1b0651 100644 (file)
@@ -540,8 +540,10 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
                     struct btrfs_delayed_ref_head *head_ref,
                     struct btrfs_qgroup_extent_record *qrecord,
                     u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved,
-                    int action, int is_data, int *qrecord_inserted_ret,
+                    int action, int is_data, int is_system,
+                    int *qrecord_inserted_ret,
                     int *old_ref_mod, int *new_ref_mod)
+
 {
        struct btrfs_delayed_ref_head *existing;
        struct btrfs_delayed_ref_root *delayed_refs;
@@ -585,6 +587,7 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
        head_ref->ref_mod = count_mod;
        head_ref->must_insert_reserved = must_insert_reserved;
        head_ref->is_data = is_data;
+       head_ref->is_system = is_system;
        head_ref->ref_tree = RB_ROOT;
        INIT_LIST_HEAD(&head_ref->ref_add_list);
        RB_CLEAR_NODE(&head_ref->href_node);
@@ -772,6 +775,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_qgroup_extent_record *record = NULL;
        int qrecord_inserted;
+       int is_system = (ref_root == BTRFS_CHUNK_TREE_OBJECTID);
 
        BUG_ON(extent_op && extent_op->is_data);
        ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
@@ -800,8 +804,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
         */
        head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
                                        bytenr, num_bytes, 0, 0, action, 0,
-                                       &qrecord_inserted, old_ref_mod,
-                                       new_ref_mod);
+                                       is_system, &qrecord_inserted,
+                                       old_ref_mod, new_ref_mod);
 
        add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
                             num_bytes, parent, ref_root, level, action);
@@ -868,7 +872,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
         */
        head_ref = add_delayed_ref_head(fs_info, trans, head_ref, record,
                                        bytenr, num_bytes, ref_root, reserved,
-                                       action, 1, &qrecord_inserted,
+                                       action, 1, 0, &qrecord_inserted,
                                        old_ref_mod, new_ref_mod);
 
        add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
@@ -898,9 +902,14 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
        delayed_refs = &trans->transaction->delayed_refs;
        spin_lock(&delayed_refs->lock);
 
+       /*
+        * extent_ops just modify the flags of an extent and they don't result
+        * in ref count changes, hence it's safe to pass false/0 for is_system
+        * argument
+        */
        add_delayed_ref_head(fs_info, trans, head_ref, NULL, bytenr,
                             num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD,
-                            extent_op->is_data, NULL, NULL, NULL);
+                            extent_op->is_data, 0, NULL, NULL, NULL);
 
        spin_unlock(&delayed_refs->lock);
        return 0;
index 741869d..7f00db5 100644 (file)
@@ -127,6 +127,7 @@ struct btrfs_delayed_ref_head {
         */
        unsigned int must_insert_reserved:1;
        unsigned int is_data:1;
+       unsigned int is_system:1;
        unsigned int processing:1;
 };
 
index 4ac8b1d..60caa68 100644 (file)
@@ -1824,6 +1824,7 @@ static int transaction_kthread(void *arg)
 
                now = get_seconds();
                if (cur->state < TRANS_STATE_BLOCKED &&
+                   !test_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags) &&
                    (now < cur->start_time ||
                     now - cur->start_time < fs_info->commit_interval)) {
                        spin_unlock(&fs_info->trans_lock);
index 75cfb80..e2f16b6 100644 (file)
@@ -2601,13 +2601,19 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
        trace_run_delayed_ref_head(fs_info, head, 0);
 
        if (head->total_ref_mod < 0) {
-               struct btrfs_block_group_cache *cache;
+               struct btrfs_space_info *space_info;
+               u64 flags;
 
-               cache = btrfs_lookup_block_group(fs_info, head->bytenr);
-               ASSERT(cache);
-               percpu_counter_add(&cache->space_info->total_bytes_pinned,
+               if (head->is_data)
+                       flags = BTRFS_BLOCK_GROUP_DATA;
+               else if (head->is_system)
+                       flags = BTRFS_BLOCK_GROUP_SYSTEM;
+               else
+                       flags = BTRFS_BLOCK_GROUP_METADATA;
+               space_info = __find_space_info(fs_info, flags);
+               ASSERT(space_info);
+               percpu_counter_add(&space_info->total_bytes_pinned,
                                   -head->num_bytes);
-               btrfs_put_block_group(cache);
 
                if (head->is_data) {
                        spin_lock(&delayed_refs->lock);
@@ -5559,14 +5565,18 @@ again:
 
 static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
                                    struct btrfs_block_rsv *block_rsv,
-                                   struct btrfs_block_rsv *dest, u64 num_bytes)
+                                   struct btrfs_block_rsv *dest, u64 num_bytes,
+                                   u64 *qgroup_to_release_ret)
 {
        struct btrfs_space_info *space_info = block_rsv->space_info;
+       u64 qgroup_to_release = 0;
        u64 ret;
 
        spin_lock(&block_rsv->lock);
-       if (num_bytes == (u64)-1)
+       if (num_bytes == (u64)-1) {
                num_bytes = block_rsv->size;
+               qgroup_to_release = block_rsv->qgroup_rsv_size;
+       }
        block_rsv->size -= num_bytes;
        if (block_rsv->reserved >= block_rsv->size) {
                num_bytes = block_rsv->reserved - block_rsv->size;
@@ -5575,6 +5585,13 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
        } else {
                num_bytes = 0;
        }
+       if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
+               qgroup_to_release = block_rsv->qgroup_rsv_reserved -
+                                   block_rsv->qgroup_rsv_size;
+               block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
+       } else {
+               qgroup_to_release = 0;
+       }
        spin_unlock(&block_rsv->lock);
 
        ret = num_bytes;
@@ -5597,6 +5614,8 @@ static u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
                        space_info_add_old_bytes(fs_info, space_info,
                                                 num_bytes);
        }
+       if (qgroup_to_release_ret)
+               *qgroup_to_release_ret = qgroup_to_release;
        return ret;
 }
 
@@ -5738,17 +5757,21 @@ static int btrfs_inode_rsv_refill(struct btrfs_inode *inode,
        struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 num_bytes = 0;
+       u64 qgroup_num_bytes = 0;
        int ret = -ENOSPC;
 
        spin_lock(&block_rsv->lock);
        if (block_rsv->reserved < block_rsv->size)
                num_bytes = block_rsv->size - block_rsv->reserved;
+       if (block_rsv->qgroup_rsv_reserved < block_rsv->qgroup_rsv_size)
+               qgroup_num_bytes = block_rsv->qgroup_rsv_size -
+                                  block_rsv->qgroup_rsv_reserved;
        spin_unlock(&block_rsv->lock);
 
        if (num_bytes == 0)
                return 0;
 
-       ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true);
+       ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_num_bytes, true);
        if (ret)
                return ret;
        ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
@@ -5756,7 +5779,13 @@ static int btrfs_inode_rsv_refill(struct btrfs_inode *inode,
                block_rsv_add_bytes(block_rsv, num_bytes, 0);
                trace_btrfs_space_reservation(root->fs_info, "delalloc",
                                              btrfs_ino(inode), num_bytes, 1);
-       }
+
+               /* Don't forget to increase qgroup_rsv_reserved */
+               spin_lock(&block_rsv->lock);
+               block_rsv->qgroup_rsv_reserved += qgroup_num_bytes;
+               spin_unlock(&block_rsv->lock);
+       } else
+               btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
        return ret;
 }
 
@@ -5777,20 +5806,23 @@ static void btrfs_inode_rsv_release(struct btrfs_inode *inode, bool qgroup_free)
        struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 released = 0;
+       u64 qgroup_to_release = 0;
 
        /*
         * Since we statically set the block_rsv->size we just want to say we
         * are releasing 0 bytes, and then we'll just get the reservation over
         * the size free'd.
         */
-       released = block_rsv_release_bytes(fs_info, block_rsv, global_rsv, 0);
+       released = block_rsv_release_bytes(fs_info, block_rsv, global_rsv, 0,
+                                          &qgroup_to_release);
        if (released > 0)
                trace_btrfs_space_reservation(fs_info, "delalloc",
                                              btrfs_ino(inode), released, 0);
        if (qgroup_free)
-               btrfs_qgroup_free_meta_prealloc(inode->root, released);
+               btrfs_qgroup_free_meta_prealloc(inode->root, qgroup_to_release);
        else
-               btrfs_qgroup_convert_reserved_meta(inode->root, released);
+               btrfs_qgroup_convert_reserved_meta(inode->root,
+                                                  qgroup_to_release);
 }
 
 void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
@@ -5802,7 +5834,7 @@ void btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
        if (global_rsv == block_rsv ||
            block_rsv->space_info != global_rsv->space_info)
                global_rsv = NULL;
-       block_rsv_release_bytes(fs_info, block_rsv, global_rsv, num_bytes);
+       block_rsv_release_bytes(fs_info, block_rsv, global_rsv, num_bytes, NULL);
 }
 
 static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
@@ -5882,7 +5914,7 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
 static void release_global_block_rsv(struct btrfs_fs_info *fs_info)
 {
        block_rsv_release_bytes(fs_info, &fs_info->global_block_rsv, NULL,
-                               (u64)-1);
+                               (u64)-1, NULL);
        WARN_ON(fs_info->trans_block_rsv.size > 0);
        WARN_ON(fs_info->trans_block_rsv.reserved > 0);
        WARN_ON(fs_info->chunk_block_rsv.size > 0);
@@ -5906,7 +5938,7 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans)
        WARN_ON_ONCE(!list_empty(&trans->new_bgs));
 
        block_rsv_release_bytes(fs_info, &fs_info->chunk_block_rsv, NULL,
-                               trans->chunk_bytes_reserved);
+                               trans->chunk_bytes_reserved, NULL);
        trans->chunk_bytes_reserved = 0;
 }
 
@@ -6011,6 +6043,7 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
 {
        struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
        u64 reserve_size = 0;
+       u64 qgroup_rsv_size = 0;
        u64 csum_leaves;
        unsigned outstanding_extents;
 
@@ -6023,9 +6056,17 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
                                                 inode->csum_bytes);
        reserve_size += btrfs_calc_trans_metadata_size(fs_info,
                                                       csum_leaves);
+       /*
+        * For qgroup rsv, the calculation is very simple:
+        * account one nodesize for each outstanding extent
+        *
+        * This is overestimating in most cases.
+        */
+       qgroup_rsv_size = outstanding_extents * fs_info->nodesize;
 
        spin_lock(&block_rsv->lock);
        block_rsv->size = reserve_size;
+       block_rsv->qgroup_rsv_size = qgroup_rsv_size;
        spin_unlock(&block_rsv->lock);
 }
 
@@ -8403,7 +8444,7 @@ static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
                            struct btrfs_block_rsv *block_rsv, u32 blocksize)
 {
        block_rsv_add_bytes(block_rsv, blocksize, 0);
-       block_rsv_release_bytes(fs_info, block_rsv, NULL, 0);
+       block_rsv_release_bytes(fs_info, block_rsv, NULL, 0, NULL);
 }
 
 /*
index 0167a9c..f660ba1 100644 (file)
@@ -1748,7 +1748,7 @@ again:
                        unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                                             lockstart, lockend, &cached_state);
                btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes,
-                                              (ret != 0));
+                                              true);
                if (ret) {
                        btrfs_drop_pages(pages, num_pages);
                        break;
index e064c49..d241285 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/uio.h>
 #include <linux/magic.h>
 #include <linux/iversion.h>
+#include <asm/unaligned.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -5905,11 +5906,13 @@ static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx)
                struct dir_entry *entry = addr;
                char *name = (char *)(entry + 1);
 
-               ctx->pos = entry->offset;
-               if (!dir_emit(ctx, name, entry->name_len, entry->ino,
-                             entry->type))
+               ctx->pos = get_unaligned(&entry->offset);
+               if (!dir_emit(ctx, name, get_unaligned(&entry->name_len),
+                                        get_unaligned(&entry->ino),
+                                        get_unaligned(&entry->type)))
                        return 1;
-               addr += sizeof(struct dir_entry) + entry->name_len;
+               addr += sizeof(struct dir_entry) +
+                       get_unaligned(&entry->name_len);
                ctx->pos++;
        }
        return 0;
@@ -5999,14 +6002,15 @@ again:
                }
 
                entry = addr;
-               entry->name_len = name_len;
+               put_unaligned(name_len, &entry->name_len);
                name_ptr = (char *)(entry + 1);
                read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1),
                                   name_len);
-               entry->type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
+               put_unaligned(btrfs_filetype_table[btrfs_dir_type(leaf, di)],
+                               &entry->type);
                btrfs_dir_item_key_to_cpu(leaf, di, &location);
-               entry->ino = location.objectid;
-               entry->offset = found_key.offset;
+               put_unaligned(location.objectid, &entry->ino);
+               put_unaligned(found_key.offset, &entry->offset);
                entries++;
                addr += sizeof(struct dir_entry) + name_len;
                total_len += sizeof(struct dir_entry) + name_len;
index 124276b..21a831d 100644 (file)
@@ -189,9 +189,10 @@ void btrfs_print_leaf(struct extent_buffer *l)
        fs_info = l->fs_info;
        nr = btrfs_header_nritems(l);
 
-       btrfs_info(fs_info, "leaf %llu total ptrs %d free space %d",
-                  btrfs_header_bytenr(l), nr,
-                  btrfs_leaf_free_space(fs_info, l));
+       btrfs_info(fs_info,
+                  "leaf %llu gen %llu total ptrs %d free space %d owner %llu",
+                  btrfs_header_bytenr(l), btrfs_header_generation(l), nr,
+                  btrfs_leaf_free_space(fs_info, l), btrfs_header_owner(l));
        for (i = 0 ; i < nr ; i++) {
                item = btrfs_item_nr(i);
                btrfs_item_key_to_cpu(l, &key, i);
@@ -325,7 +326,7 @@ void btrfs_print_leaf(struct extent_buffer *l)
        }
 }
 
-void btrfs_print_tree(struct extent_buffer *c)
+void btrfs_print_tree(struct extent_buffer *c, bool follow)
 {
        struct btrfs_fs_info *fs_info;
        int i; u32 nr;
@@ -342,15 +343,19 @@ void btrfs_print_tree(struct extent_buffer *c)
                return;
        }
        btrfs_info(fs_info,
-                  "node %llu level %d total ptrs %d free spc %u",
-                  btrfs_header_bytenr(c), level, nr,
-                  (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr);
+                  "node %llu level %d gen %llu total ptrs %d free spc %u owner %llu",
+                  btrfs_header_bytenr(c), level, btrfs_header_generation(c),
+                  nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(fs_info) - nr,
+                  btrfs_header_owner(c));
        for (i = 0; i < nr; i++) {
                btrfs_node_key_to_cpu(c, &key, i);
-               pr_info("\tkey %d (%llu %u %llu) block %llu\n",
+               pr_info("\tkey %d (%llu %u %llu) block %llu gen %llu\n",
                       i, key.objectid, key.type, key.offset,
-                      btrfs_node_blockptr(c, i));
+                      btrfs_node_blockptr(c, i),
+                      btrfs_node_ptr_generation(c, i));
        }
+       if (!follow)
+               return;
        for (i = 0; i < nr; i++) {
                struct btrfs_key first_key;
                struct extent_buffer *next;
@@ -372,7 +377,7 @@ void btrfs_print_tree(struct extent_buffer *c)
                if (btrfs_header_level(next) !=
                       level - 1)
                        BUG();
-               btrfs_print_tree(next);
+               btrfs_print_tree(next, follow);
                free_extent_buffer(next);
        }
 }
index 4a98481..e6bb38f 100644 (file)
@@ -7,6 +7,6 @@
 #define BTRFS_PRINT_TREE_H
 
 void btrfs_print_leaf(struct extent_buffer *l);
-void btrfs_print_tree(struct extent_buffer *c);
+void btrfs_print_tree(struct extent_buffer *c, bool follow);
 
 #endif
index 09c7e4f..9fb758d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/btrfs.h>
+#include <linux/sizes.h>
 
 #include "ctree.h"
 #include "transaction.h"
@@ -2375,8 +2376,21 @@ out:
        return ret;
 }
 
-static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
+/*
+ * Two limits to commit transaction in advance.
+ *
+ * For RATIO, it will be 1/RATIO of the remaining limit
+ * (excluding data and prealloc meta) as threshold.
+ * For SIZE, it will be in byte unit as threshold.
+ */
+#define QGROUP_PERTRANS_RATIO          32
+#define QGROUP_PERTRANS_SIZE           SZ_32M
+static bool qgroup_check_limits(struct btrfs_fs_info *fs_info,
+                               const struct btrfs_qgroup *qg, u64 num_bytes)
 {
+       u64 limit;
+       u64 threshold;
+
        if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
            qgroup_rsv_total(qg) + (s64)qg->rfer + num_bytes > qg->max_rfer)
                return false;
@@ -2385,6 +2399,31 @@ static bool qgroup_check_limits(const struct btrfs_qgroup *qg, u64 num_bytes)
            qgroup_rsv_total(qg) + (s64)qg->excl + num_bytes > qg->max_excl)
                return false;
 
+       /*
+        * Even if we passed the check, it's better to check if reservation
+        * for meta_pertrans is pushing us near limit.
+        * If there is too much pertrans reservation or it's near the limit,
+        * let's try commit transaction to free some, using transaction_kthread
+        */
+       if ((qg->lim_flags & (BTRFS_QGROUP_LIMIT_MAX_RFER |
+                             BTRFS_QGROUP_LIMIT_MAX_EXCL))) {
+               if (qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL)
+                       limit = qg->max_excl;
+               else
+                       limit = qg->max_rfer;
+               threshold = (limit - qg->rsv.values[BTRFS_QGROUP_RSV_DATA] -
+                           qg->rsv.values[BTRFS_QGROUP_RSV_META_PREALLOC]) /
+                           QGROUP_PERTRANS_RATIO;
+               threshold = min_t(u64, threshold, QGROUP_PERTRANS_SIZE);
+
+               /*
+                * Use transaction_kthread to commit transaction, so we no
+                * longer need to bother nested transaction nor lock context.
+                */
+               if (qg->rsv.values[BTRFS_QGROUP_RSV_META_PERTRANS] > threshold)
+                       btrfs_commit_transaction_locksafe(fs_info);
+       }
+
        return true;
 }
 
@@ -2434,7 +2473,7 @@ static int qgroup_reserve(struct btrfs_root *root, u64 num_bytes, bool enforce,
 
                qg = unode_aux_to_qgroup(unode);
 
-               if (enforce && !qgroup_check_limits(qg, num_bytes)) {
+               if (enforce && !qgroup_check_limits(fs_info, qg, num_bytes)) {
                        ret = -EDQUOT;
                        goto out;
                }
index 63fdcab..c944b47 100644 (file)
@@ -2267,6 +2267,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         */
        cur_trans->state = TRANS_STATE_COMPLETED;
        wake_up(&cur_trans->commit_wait);
+       clear_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags);
 
        spin_lock(&fs_info->trans_lock);
        list_del_init(&cur_trans->list);
index c88fccd..d8c0826 100644 (file)
@@ -199,6 +199,20 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root);
 int btrfs_commit_transaction(struct btrfs_trans_handle *trans);
 int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
                                   int wait_for_unblock);
+
+/*
+ * Try to commit transaction asynchronously, so this is safe to call
+ * even holding a spinlock.
+ *
+ * It's done by informing transaction_kthread to commit transaction without
+ * waiting for commit interval.
+ */
+static inline void btrfs_commit_transaction_locksafe(
+               struct btrfs_fs_info *fs_info)
+{
+       set_bit(BTRFS_FS_NEED_ASYNC_COMMIT, &fs_info->flags);
+       wake_up_process(fs_info->transaction_kthread);
+}
 int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans);
 int btrfs_should_end_transaction(struct btrfs_trans_handle *trans);
 void btrfs_throttle(struct btrfs_fs_info *fs_info);
index 8bf6025..ae05692 100644 (file)
@@ -669,13 +669,15 @@ void ceph_fill_file_time(struct inode *inode, int issued,
                      CEPH_CAP_FILE_BUFFER|
                      CEPH_CAP_AUTH_EXCL|
                      CEPH_CAP_XATTR_EXCL)) {
-               if (timespec_compare(ctime, &inode->i_ctime) > 0) {
+               if (ci->i_version == 0 ||
+                   timespec_compare(ctime, &inode->i_ctime) > 0) {
                        dout("ctime %ld.%09ld -> %ld.%09ld inc w/ cap\n",
                             inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
                             ctime->tv_sec, ctime->tv_nsec);
                        inode->i_ctime = *ctime;
                }
-               if (ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
+               if (ci->i_version == 0 ||
+                   ceph_seq_cmp(time_warp_seq, ci->i_time_warp_seq) > 0) {
                        /* the MDS did a utimes() */
                        dout("mtime %ld.%09ld -> %ld.%09ld "
                             "tw %d -> %d\n",
@@ -795,7 +797,6 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
        new_issued = ~issued & le32_to_cpu(info->cap.caps);
 
        /* update inode */
-       ci->i_version = le64_to_cpu(info->version);
        inode->i_rdev = le32_to_cpu(info->rdev);
        inode->i_blkbits = fls(le32_to_cpu(info->layout.fl_stripe_unit)) - 1;
 
@@ -868,6 +869,9 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
                xattr_blob = NULL;
        }
 
+       /* finally update i_version */
+       ci->i_version = le64_to_cpu(info->version);
+
        inode->i_mapping->a_ops = &ceph_aops;
 
        switch (inode->i_mode & S_IFMT) {
index fe55676..0e74690 100644 (file)
@@ -54,7 +54,7 @@ do {                                                          \
                pr_debug_ ## ratefunc("%s: "                    \
                                fmt, __FILE__, ##__VA_ARGS__);  \
        } else if ((type) & VFS) {                              \
-               pr_err_ ## ratefunc("CuIFS VFS: "               \
+               pr_err_ ## ratefunc("CIFS VFS: "                \
                                 fmt, ##__VA_ARGS__);           \
        } else if ((type) & NOISY && (NOISY != 0)) {            \
                pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__);      \
index 81ba6e0..9258443 100644 (file)
@@ -684,6 +684,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
                goto mknod_out;
        }
 
+       if (!S_ISCHR(mode) && !S_ISBLK(mode))
+               goto mknod_out;
+
        if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
                goto mknod_out;
 
@@ -692,10 +695,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
 
        buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
        if (buf == NULL) {
-               kfree(full_path);
                rc = -ENOMEM;
-               free_xid(xid);
-               return rc;
+               goto mknod_out;
        }
 
        if (backup_cred(cifs_sb))
@@ -742,7 +743,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
                pdev->minor = cpu_to_le64(MINOR(device_number));
                rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
                                                        &bytes_written, iov, 1);
-       } /* else if (S_ISFIFO) */
+       }
        tcon->ses->server->ops->close(xid, tcon, &fid);
        d_drop(direntry);
 
index 4bcd4e8..23fd430 100644 (file)
@@ -3462,7 +3462,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
  * If the page is mmap'ed into a process' page tables, then we need to make
  * sure that it doesn't change while being written back.
  */
-static int
+static vm_fault_t
 cifs_page_mkwrite(struct vm_fault *vmf)
 {
        struct page *page = vmf->page;
index b4ae932..38ebf3f 100644 (file)
@@ -1452,7 +1452,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
        struct kvec err_iov = {NULL, 0};
-       struct smb2_err_rsp *err_buf = NULL;
+       struct smb2_err_rsp *err_buf;
        struct smb2_symlink_err_rsp *symlink;
        unsigned int sub_len;
        unsigned int sub_offset;
@@ -1476,7 +1476,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_iov);
 
-       if (!rc || !err_buf) {
+       if (!rc || !err_iov.iov_base) {
                kfree(utf16_path);
                return -ENOENT;
        }
index 5008af5..87817dd 100644 (file)
@@ -1028,7 +1028,7 @@ static int smbd_post_send(struct smbd_connection *info,
        for (i = 0; i < request->num_sge; i++) {
                log_rdma_send(INFO,
                        "rdma_request sge[%d] addr=%llu length=%u\n",
-                       i, request->sge[0].addr, request->sge[0].length);
+                       i, request->sge[i].addr, request->sge[i].length);
                ib_dma_sync_single_for_device(
                        info->id->device,
                        request->sge[i].addr,
@@ -2139,6 +2139,10 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
                goto done;
        }
 
+       cifs_dbg(FYI, "Sending smb (RDMA): smb_len=%u\n", buflen);
+       for (i = 0; i < rqst->rq_nvec-1; i++)
+               dump_smb(iov[i].iov_base, iov[i].iov_len);
+
        remaining_data_length = buflen;
 
        log_write(INFO, "rqst->rq_nvec=%d rqst->rq_npages=%d rq_pagesz=%d "
@@ -2194,6 +2198,8 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
                                                goto done;
                                }
                                i++;
+                               if (i == rqst->rq_nvec)
+                                       break;
                        }
                        start = i;
                        buflen = 0;
index 846ca15..4dd842f 100644 (file)
@@ -1997,6 +1997,16 @@ out:
        return rc;
 }
 
+static bool is_dot_dotdot(const char *name, size_t name_size)
+{
+       if (name_size == 1 && name[0] == '.')
+               return true;
+       else if (name_size == 2 && name[0] == '.' && name[1] == '.')
+               return true;
+
+       return false;
+}
+
 /**
  * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext
  * @plaintext_name: The plaintext name
@@ -2021,13 +2031,21 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
        size_t packet_size;
        int rc = 0;
 
-       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-           && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
-           && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)
-           && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
-                       ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) {
-               const char *orig_name = name;
-               size_t orig_name_size = name_size;
+       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) &&
+           !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)) {
+               if (is_dot_dotdot(name, name_size)) {
+                       rc = ecryptfs_copy_filename(plaintext_name,
+                                                   plaintext_name_size,
+                                                   name, name_size);
+                       goto out;
+               }
+
+               if (name_size <= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE ||
+                   strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
+                           ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)) {
+                       rc = -EINVAL;
+                       goto out;
+               }
 
                name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
                name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE;
@@ -2047,12 +2065,9 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
                                                  decoded_name,
                                                  decoded_name_size);
                if (rc) {
-                       printk(KERN_INFO "%s: Could not parse tag 70 packet "
-                              "from filename; copying through filename "
-                              "as-is\n", __func__);
-                       rc = ecryptfs_copy_filename(plaintext_name,
-                                                   plaintext_name_size,
-                                                   orig_name, orig_name_size);
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Could not parse tag 70 packet from filename\n",
+                                       __func__);
                        goto out_free;
                }
        } else {
index c74ed3c..b76a985 100644 (file)
@@ -82,17 +82,28 @@ ecryptfs_filldir(struct dir_context *ctx, const char *lower_name,
                                                  buf->sb, lower_name,
                                                  lower_namelen);
        if (rc) {
-               printk(KERN_ERR "%s: Error attempting to decode and decrypt "
-                      "filename [%s]; rc = [%d]\n", __func__, lower_name,
-                      rc);
-               goto out;
+               if (rc != -EINVAL) {
+                       ecryptfs_printk(KERN_DEBUG,
+                                       "%s: Error attempting to decode and decrypt filename [%s]; rc = [%d]\n",
+                                       __func__, lower_name, rc);
+                       return rc;
+               }
+
+               /* Mask -EINVAL errors as these are most likely due a plaintext
+                * filename present in the lower filesystem despite filename
+                * encryption being enabled. One unavoidable example would be
+                * the "lost+found" dentry in the root directory of an Ext4
+                * filesystem.
+                */
+               return 0;
        }
+
        buf->caller->pos = buf->ctx.pos;
        rc = !dir_emit(buf->caller, name, name_size, ino, d_type);
        kfree(name);
        if (!rc)
                buf->entries_written++;
-out:
+
        return rc;
 }
 
index 847904a..97d17ea 100644 (file)
@@ -395,8 +395,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
                                ecryptfs_dentry->d_sb)->mount_crypt_stat;
-       if (mount_crypt_stat
-           && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
                rc = ecryptfs_encrypt_and_encode_filename(
                        &encrypted_and_encoded_name, &len,
                        mount_crypt_stat, name, len);
index c89a58c..e74fe84 100644 (file)
@@ -1880,7 +1880,7 @@ find_next_matching_auth_tok:
                candidate_auth_tok = &auth_tok_list_item->auth_tok;
                if (unlikely(ecryptfs_verbosity > 0)) {
                        ecryptfs_printk(KERN_DEBUG,
-                                       "Considering cadidate auth tok:\n");
+                                       "Considering candidate auth tok:\n");
                        ecryptfs_dump_auth_tok(candidate_auth_tok);
                }
                rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig,
index 0964022..047c327 100644 (file)
@@ -88,11 +88,11 @@ out_unlock:
  * The default page_lock and i_size verification done by non-DAX fault paths
  * is sufficient because ext2 doesn't support hole punching.
  */
-static int ext2_dax_fault(struct vm_fault *vmf)
+static vm_fault_t ext2_dax_fault(struct vm_fault *vmf)
 {
        struct inode *inode = file_inode(vmf->vma->vm_file);
        struct ext2_inode_info *ei = EXT2_I(inode);
-       int ret;
+       vm_fault_t ret;
 
        if (vmf->flags & FAULT_FLAG_WRITE) {
                sb_start_pagefault(inode->i_sb);
index 4b12ba7..47d7c15 100644 (file)
@@ -745,11 +745,12 @@ int inode_congested(struct inode *inode, int cong_bits)
         */
        if (inode && inode_to_wb_is_valid(inode)) {
                struct bdi_writeback *wb;
-               bool locked, congested;
+               struct wb_lock_cookie lock_cookie = {};
+               bool congested;
 
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &lock_cookie);
                congested = wb_congested(wb, cong_bits);
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &lock_cookie);
                return congested;
        }
 
index 9bb2fe3..10205ec 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/bio.h>
 
+#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/zlib.h>
 
@@ -59,7 +60,7 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
                                >> bufshift;
        int haveblocks;
        blkcnt_t blocknum;
-       struct buffer_head *bhs[needblocks + 1];
+       struct buffer_head **bhs;
        int curbh, curpage;
 
        if (block_size > deflateBound(1UL << zisofs_block_shift)) {
@@ -80,7 +81,11 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start,
 
        /* Because zlib is not thread-safe, do all the I/O at the top. */
        blocknum = block_start >> bufshift;
-       memset(bhs, 0, (needblocks + 1) * sizeof(struct buffer_head *));
+       bhs = kcalloc(needblocks + 1, sizeof(*bhs), GFP_KERNEL);
+       if (!bhs) {
+               *errp = -ENOMEM;
+               return 0;
+       }
        haveblocks = isofs_get_blocks(inode, blocknum, bhs, needblocks);
        ll_rw_block(REQ_OP_READ, 0, haveblocks, bhs);
 
@@ -190,6 +195,7 @@ z_eio:
 b_eio:
        for (i = 0; i < haveblocks; i++)
                brelse(bhs[i]);
+       kfree(bhs);
        return stream.total_out;
 }
 
@@ -305,7 +311,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
        unsigned int zisofs_pages_per_cblock =
                PAGE_SHIFT <= zisofs_block_shift ?
                (1 << (zisofs_block_shift - PAGE_SHIFT)) : 0;
-       struct page *pages[max_t(unsigned, zisofs_pages_per_cblock, 1)];
+       struct page **pages;
        pgoff_t index = page->index, end_index;
 
        end_index = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -330,6 +336,12 @@ static int zisofs_readpage(struct file *file, struct page *page)
                full_page = 0;
                pcount = 1;
        }
+       pages = kcalloc(max_t(unsigned int, zisofs_pages_per_cblock, 1),
+                                       sizeof(*pages), GFP_KERNEL);
+       if (!pages) {
+               unlock_page(page);
+               return -ENOMEM;
+       }
        pages[full_page] = page;
 
        for (i = 0; i < pcount; i++, index++) {
@@ -357,6 +369,7 @@ static int zisofs_readpage(struct file *file, struct page *page)
        }                       
 
        /* At this point, err contains 0 or -EIO depending on the "critical" page */
+       kfree(pages);
        return err;
 }
 
index bc258a4..ec3fba7 100644 (file)
@@ -394,7 +394,10 @@ static int parse_options(char *options, struct iso9660_options *popt)
                        break;
 #ifdef CONFIG_JOLIET
                case Opt_iocharset:
+                       kfree(popt->iocharset);
                        popt->iocharset = match_strdup(&args[0]);
+                       if (!popt->iocharset)
+                               return 0;
                        break;
 #endif
                case Opt_map_a:
index f60dee7..87bdf0f 100644 (file)
@@ -342,7 +342,7 @@ static void jffs2_put_super (struct super_block *sb)
 static void jffs2_kill_sb(struct super_block *sb)
 {
        struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-       if (!sb_rdonly(sb))
+       if (c && !sb_rdonly(sb))
                jffs2_stop_garbage_collect_thread(c);
        kill_mtd_super(sb);
        kfree(c);
index e398f32..5f75969 100644 (file)
@@ -1089,7 +1089,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
                        goto out_free;
        }
 
-       mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED);
+       mnt->mnt.mnt_flags = old->mnt.mnt_flags;
+       mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
        /* Don't allow unprivileged users to change mount flags */
        if (flag & CL_UNPRIVILEGED) {
                mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
@@ -2814,7 +2815,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
                mnt_flags |= MNT_NODIRATIME;
        if (flags & MS_STRICTATIME)
                mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
-       if (flags & SB_RDONLY)
+       if (flags & MS_RDONLY)
                mnt_flags |= MNT_READONLY;
 
        /* The default atime for remount is preservation */
index d51e1bb..d94e803 100644 (file)
@@ -92,7 +92,7 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
                                       u32 event_mask,
                                       const void *data, int data_type)
 {
-       __u32 marks_mask, marks_ignored_mask;
+       __u32 marks_mask = 0, marks_ignored_mask = 0;
        const struct path *path = data;
 
        pr_debug("%s: inode_mark=%p vfsmnt_mark=%p mask=%x data=%p"
@@ -108,24 +108,20 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark,
            !d_can_lookup(path->dentry))
                return false;
 
-       if (inode_mark && vfsmnt_mark) {
-               marks_mask = (vfsmnt_mark->mask | inode_mark->mask);
-               marks_ignored_mask = (vfsmnt_mark->ignored_mask | inode_mark->ignored_mask);
-       } else if (inode_mark) {
-               /*
-                * if the event is for a child and this inode doesn't care about
-                * events on the child, don't send it!
-                */
-               if ((event_mask & FS_EVENT_ON_CHILD) &&
-                   !(inode_mark->mask & FS_EVENT_ON_CHILD))
-                       return false;
-               marks_mask = inode_mark->mask;
-               marks_ignored_mask = inode_mark->ignored_mask;
-       } else if (vfsmnt_mark) {
-               marks_mask = vfsmnt_mark->mask;
-               marks_ignored_mask = vfsmnt_mark->ignored_mask;
-       } else {
-               BUG();
+       /*
+        * if the event is for a child and this inode doesn't care about
+        * events on the child, don't send it!
+        */
+       if (inode_mark &&
+           (!(event_mask & FS_EVENT_ON_CHILD) ||
+            (inode_mark->mask & FS_EVENT_ON_CHILD))) {
+               marks_mask |= inode_mark->mask;
+               marks_ignored_mask |= inode_mark->ignored_mask;
+       }
+
+       if (vfsmnt_mark) {
+               marks_mask |= vfsmnt_mark->mask;
+               marks_ignored_mask |= vfsmnt_mark->ignored_mask;
        }
 
        if (d_is_dir(path->dentry) &&
index 219b269..613ec7e 100644 (file)
@@ -192,8 +192,9 @@ static int send_to_group(struct inode *to_tell,
                         struct fsnotify_iter_info *iter_info)
 {
        struct fsnotify_group *group = NULL;
-       __u32 inode_test_mask = 0;
-       __u32 vfsmount_test_mask = 0;
+       __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD);
+       __u32 marks_mask = 0;
+       __u32 marks_ignored_mask = 0;
 
        if (unlikely(!inode_mark && !vfsmount_mark)) {
                BUG();
@@ -213,29 +214,25 @@ static int send_to_group(struct inode *to_tell,
        /* does the inode mark tell us to do something? */
        if (inode_mark) {
                group = inode_mark->group;
-               inode_test_mask = (mask & ~FS_EVENT_ON_CHILD);
-               inode_test_mask &= inode_mark->mask;
-               inode_test_mask &= ~inode_mark->ignored_mask;
+               marks_mask |= inode_mark->mask;
+               marks_ignored_mask |= inode_mark->ignored_mask;
        }
 
        /* does the vfsmount_mark tell us to do something? */
        if (vfsmount_mark) {
-               vfsmount_test_mask = (mask & ~FS_EVENT_ON_CHILD);
                group = vfsmount_mark->group;
-               vfsmount_test_mask &= vfsmount_mark->mask;
-               vfsmount_test_mask &= ~vfsmount_mark->ignored_mask;
-               if (inode_mark)
-                       vfsmount_test_mask &= ~inode_mark->ignored_mask;
+               marks_mask |= vfsmount_mark->mask;
+               marks_ignored_mask |= vfsmount_mark->ignored_mask;
        }
 
        pr_debug("%s: group=%p to_tell=%p mask=%x inode_mark=%p"
-                " inode_test_mask=%x vfsmount_mark=%p vfsmount_test_mask=%x"
+                " vfsmount_mark=%p marks_mask=%x marks_ignored_mask=%x"
                 " data=%p data_is=%d cookie=%d\n",
-                __func__, group, to_tell, mask, inode_mark,
-                inode_test_mask, vfsmount_mark, vfsmount_test_mask, data,
+                __func__, group, to_tell, mask, inode_mark, vfsmount_mark,
+                marks_mask, marks_ignored_mask, data,
                 data_is, cookie);
 
-       if (!inode_test_mask && !vfsmount_test_mask)
+       if (!(test_mask & marks_mask & ~marks_ignored_mask))
                return 0;
 
        return group->ops->handle_event(group, to_tell, inode_mark,
index 3ae5fdb..10796d3 100644 (file)
@@ -579,6 +579,11 @@ void orangefs_kill_sb(struct super_block *sb)
        /* provided sb cleanup */
        kill_anon_super(sb);
 
+       if (!ORANGEFS_SB(sb)) {
+               mutex_lock(&orangefs_request_mutex);
+               mutex_unlock(&orangefs_request_mutex);
+               return;
+       }
        /*
         * issue the unmount to userspace to tell it to remove the
         * dynamic mount info it has for this superblock
index eafa39a..1b2ede6 100644 (file)
@@ -1693,6 +1693,12 @@ void task_dump_owner(struct task_struct *task, umode_t mode,
        kuid_t uid;
        kgid_t gid;
 
+       if (unlikely(task->flags & PF_KTHREAD)) {
+               *ruid = GLOBAL_ROOT_UID;
+               *rgid = GLOBAL_ROOT_GID;
+               return;
+       }
+
        /* Default to the tasks effective ownership */
        rcu_read_lock();
        cred = __task_cred(task);
index a000d75..b572cc8 100644 (file)
@@ -24,7 +24,7 @@ static int loadavg_proc_show(struct seq_file *m, void *v)
                LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
                LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
                nr_running(), nr_threads,
-               idr_get_cursor(&task_active_pid_ns(current)->idr));
+               idr_get_cursor(&task_active_pid_ns(current)->idr) - 1);
        return 0;
 }
 
index ed48b6e..a20c6e4 100644 (file)
@@ -1310,9 +1310,11 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
 #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
                else if (is_swap_pmd(pmd)) {
                        swp_entry_t entry = pmd_to_swp_entry(pmd);
+                       unsigned long offset = swp_offset(entry);
 
+                       offset += (addr & ~PMD_MASK) >> PAGE_SHIFT;
                        frame = swp_type(entry) |
-                               (swp_offset(entry) << MAX_SWAPFILES_SHIFT);
+                               (offset << MAX_SWAPFILES_SHIFT);
                        flags |= PM_SWAP;
                        if (pmd_swp_soft_dirty(pmd))
                                flags |= PM_SOFT_DIRTY;
@@ -1332,6 +1334,8 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
                                break;
                        if (pm->show_pfn && (flags & PM_PRESENT))
                                frame++;
+                       else if (flags & PM_SWAP)
+                               frame += (1 << MAX_SWAPFILES_SHIFT);
                }
                spin_unlock(ptl);
                return err;
index 020c597..d88231e 100644 (file)
@@ -2966,7 +2966,7 @@ static int __init dquot_init(void)
                        NULL);
 
        order = 0;
-       dquot_hash = (struct hlist_head *)__get_free_pages(GFP_ATOMIC, order);
+       dquot_hash = (struct hlist_head *)__get_free_pages(GFP_KERNEL, order);
        if (!dquot_hash)
                panic("Cannot create dquot hash table");
 
index 5fa9a8d..122c402 100644 (file)
@@ -167,6 +167,7 @@ static void destroy_unused_super(struct super_block *s)
        security_sb_free(s);
        put_user_ns(s->s_user_ns);
        kfree(s->s_subtype);
+       free_prealloced_shrinker(&s->s_shrink);
        /* no delays needed */
        destroy_super_work(&s->destroy_work);
 }
@@ -252,6 +253,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
        s->s_shrink.count_objects = super_cache_count;
        s->s_shrink.batch = 1024;
        s->s_shrink.flags = SHRINKER_NUMA_AWARE | SHRINKER_MEMCG_AWARE;
+       if (prealloc_shrinker(&s->s_shrink))
+               goto fail;
        return s;
 
 fail:
@@ -518,11 +521,7 @@ retry:
        hlist_add_head(&s->s_instances, &type->fs_supers);
        spin_unlock(&sb_lock);
        get_filesystem(type);
-       err = register_shrinker(&s->s_shrink);
-       if (err) {
-               deactivate_locked_super(s);
-               s = ERR_PTR(err);
-       }
+       register_shrinker_prepared(&s->s_shrink);
        return s;
 }
 
index f897e55..16a8ad2 100644 (file)
@@ -28,6 +28,9 @@
 
 #include "udf_sb.h"
 
+#define SURROGATE_MASK 0xfffff800
+#define SURROGATE_PAIR 0x0000d800
+
 static int udf_uni2char_utf8(wchar_t uni,
                             unsigned char *out,
                             int boundlen)
@@ -37,6 +40,9 @@ static int udf_uni2char_utf8(wchar_t uni,
        if (boundlen <= 0)
                return -ENAMETOOLONG;
 
+       if ((uni & SURROGATE_MASK) == SURROGATE_PAIR)
+               return -EINVAL;
+
        if (uni < 0x80) {
                out[u_len++] = (unsigned char)uni;
        } else if (uni < 0x800) {
index 562fa7d..98e63d8 100644 (file)
@@ -19,7 +19,7 @@
 #define DRM_HDCP_RI_LEN                                2
 #define DRM_HDCP_V_PRIME_PART_LEN              4
 #define DRM_HDCP_V_PRIME_NUM_PARTS             5
-#define DRM_HDCP_NUM_DOWNSTREAM(x)             (x & 0x3f)
+#define DRM_HDCP_NUM_DOWNSTREAM(x)             (x & 0x7f)
 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)       (x & BIT(3))
 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)                (x & BIT(7))
 
index bfe86b5..0bd432a 100644 (file)
@@ -223,6 +223,11 @@ static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync)
        set_wb_congested(bdi->wb.congested, sync);
 }
 
+struct wb_lock_cookie {
+       bool locked;
+       unsigned long flags;
+};
+
 #ifdef CONFIG_CGROUP_WRITEBACK
 
 /**
index f6be4b0..72ca0f3 100644 (file)
@@ -347,7 +347,7 @@ static inline struct bdi_writeback *inode_to_wb(const struct inode *inode)
 /**
  * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction
  * @inode: target inode
- * @lockedp: temp bool output param, to be passed to the end function
+ * @cookie: output param, to be passed to the end function
  *
  * The caller wants to access the wb associated with @inode but isn't
  * holding inode->i_lock, the i_pages lock or wb->list_lock.  This
@@ -355,12 +355,12 @@ static inline struct bdi_writeback *inode_to_wb(const struct inode *inode)
  * association doesn't change until the transaction is finished with
  * unlocked_inode_to_wb_end().
  *
- * The caller must call unlocked_inode_to_wb_end() with *@lockdep
- * afterwards and can't sleep during transaction.  IRQ may or may not be
- * disabled on return.
+ * The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and
+ * can't sleep during the transaction.  IRQs may or may not be disabled on
+ * return.
  */
 static inline struct bdi_writeback *
-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
+unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
 {
        rcu_read_lock();
 
@@ -368,10 +368,10 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
         * Paired with store_release in inode_switch_wb_work_fn() and
         * ensures that we see the new wb if we see cleared I_WB_SWITCH.
         */
-       *lockedp = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
+       cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
 
-       if (unlikely(*lockedp))
-               xa_lock_irq(&inode->i_mapping->i_pages);
+       if (unlikely(cookie->locked))
+               xa_lock_irqsave(&inode->i_mapping->i_pages, cookie->flags);
 
        /*
         * Protected by either !I_WB_SWITCH + rcu_read_lock() or the i_pages
@@ -383,12 +383,13 @@ unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
 /**
  * unlocked_inode_to_wb_end - end inode wb access transaction
  * @inode: target inode
- * @locked: *@lockedp from unlocked_inode_to_wb_begin()
+ * @cookie: @cookie from unlocked_inode_to_wb_begin()
  */
-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
+static inline void unlocked_inode_to_wb_end(struct inode *inode,
+                                           struct wb_lock_cookie *cookie)
 {
-       if (unlikely(locked))
-               xa_unlock_irq(&inode->i_mapping->i_pages);
+       if (unlikely(cookie->locked))
+               xa_unlock_irqrestore(&inode->i_mapping->i_pages, cookie->flags);
 
        rcu_read_unlock();
 }
@@ -435,12 +436,13 @@ static inline struct bdi_writeback *inode_to_wb(struct inode *inode)
 }
 
 static inline struct bdi_writeback *
-unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
+unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
 {
        return inode_to_wb(inode);
 }
 
-static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
+static inline void unlocked_inode_to_wb_end(struct inode *inode,
+                                           struct wb_lock_cookie *cookie)
 {
 }
 
index ceb96ec..7d98e26 100644 (file)
@@ -25,6 +25,9 @@
 #define __SANITIZE_ADDRESS__
 #endif
 
+#undef __no_sanitize_address
+#define __no_sanitize_address __attribute__((no_sanitize("address")))
+
 /* Clang doesn't have a way to turn it off per-function, yet. */
 #ifdef __noretpoline
 #undef __noretpoline
index edfeaba..a1a959b 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _LINUX_CORESIGHT_PMU_H
index 9f1edb9..e0c95c9 100644 (file)
@@ -248,7 +248,7 @@ struct fsnotify_mark {
        /* Group this mark is for. Set on mark creation, stable until last ref
         * is dropped */
        struct fsnotify_group *group;
-       /* List of marks by group->i_fsnotify_marks. Also reused for queueing
+       /* List of marks by group->marks_list. Also reused for queueing
         * mark into destroy_list when it's waiting for the end of SRCU period
         * before it can be freed. [group->mark_mutex] */
        struct list_head g_list;
index 8da3e1f..26240a2 100644 (file)
@@ -516,6 +516,12 @@ enum hid_type {
        HID_TYPE_USBNONE
 };
 
+enum hid_battery_status {
+       HID_BATTERY_UNKNOWN = 0,
+       HID_BATTERY_QUERIED,            /* Kernel explicitly queried battery strength */
+       HID_BATTERY_REPORTED,           /* Device sent unsolicited battery strength report */
+};
+
 struct hid_driver;
 struct hid_ll_driver;
 
@@ -558,7 +564,8 @@ struct hid_device {                                                 /* device report descriptor */
        __s32 battery_max;
        __s32 battery_report_type;
        __s32 battery_report_id;
-       bool battery_reported;
+       enum hid_battery_status battery_status;
+       bool battery_avoid_query;
 #endif
 
        unsigned int status;                                            /* see STAT flags above */
index d11f41d..78a5a90 100644 (file)
@@ -663,7 +663,7 @@ static inline bool skb_vlan_tagged(const struct sk_buff *skb)
  * Returns true if the skb is tagged with multiple vlan headers, regardless
  * of whether it is hardware accelerated or not.
  */
-static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
+static inline bool skb_vlan_tagged_multi(struct sk_buff *skb)
 {
        __be16 protocol = skb->protocol;
 
@@ -673,6 +673,9 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
                if (likely(!eth_type_vlan(protocol)))
                        return false;
 
+               if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN)))
+                       return false;
+
                veh = (struct vlan_ethhdr *)skb->data;
                protocol = veh->h_vlan_encapsulated_proto;
        }
@@ -690,7 +693,7 @@ static inline bool skb_vlan_tagged_multi(const struct sk_buff *skb)
  *
  * Returns features without unsafe ones if the skb has multiple tags.
  */
-static inline netdev_features_t vlan_features_check(const struct sk_buff *skb,
+static inline netdev_features_t vlan_features_check(struct sk_buff *skb,
                                                    netdev_features_t features)
 {
        if (skb_vlan_tagged_multi(skb)) {
index 4754f01..aec44b1 100644 (file)
@@ -186,13 +186,20 @@ static inline bool klp_have_reliable_stack(void)
               IS_ENABLED(CONFIG_HAVE_RELIABLE_STACKTRACE);
 }
 
+typedef int (*klp_shadow_ctor_t)(void *obj,
+                                void *shadow_data,
+                                void *ctor_data);
+typedef void (*klp_shadow_dtor_t)(void *obj, void *shadow_data);
+
 void *klp_shadow_get(void *obj, unsigned long id);
-void *klp_shadow_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags);
-void *klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                             size_t size, gfp_t gfp_flags);
-void klp_shadow_free(void *obj, unsigned long id);
-void klp_shadow_free_all(unsigned long id);
+void *klp_shadow_alloc(void *obj, unsigned long id,
+                      size_t size, gfp_t gfp_flags,
+                      klp_shadow_ctor_t ctor, void *ctor_data);
+void *klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                             size_t size, gfp_t gfp_flags,
+                             klp_shadow_ctor_t ctor, void *ctor_data);
+void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor);
+void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor);
 
 #else /* !CONFIG_LIVEPATCH */
 
index eb492d4..8f9c903 100644 (file)
 #define        LAN88XX_MMD3_CHIP_ID                    (32877)
 #define        LAN88XX_MMD3_CHIP_REV                   (32878)
 
+/* DSP registers */
+#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG         (0x806A)
+#define PHY_ARDENNES_MMD_DEV_3_PHY_CFG_ZD_DLY_EN_      (0x2000)
+#define LAN88XX_EXT_PAGE_ACCESS_TR             (0x52B5)
+#define LAN88XX_EXT_PAGE_TR_CR                 16
+#define LAN88XX_EXT_PAGE_TR_LOW_DATA           17
+#define LAN88XX_EXT_PAGE_TR_HIGH_DATA          18
+
 #endif /* _MICROCHIPPHY_H */
index 388ff29..6794490 100644 (file)
@@ -75,6 +75,9 @@ struct shrinker {
 #define SHRINKER_NUMA_AWARE    (1 << 0)
 #define SHRINKER_MEMCG_AWARE   (1 << 1)
 
-extern int register_shrinker(struct shrinker *);
-extern void unregister_shrinker(struct shrinker *);
+extern int prealloc_shrinker(struct shrinker *shrinker);
+extern void register_shrinker_prepared(struct shrinker *shrinker);
+extern int register_shrinker(struct shrinker *shrinker);
+extern void unregister_shrinker(struct shrinker *shrinker);
+extern void free_prealloced_shrinker(struct shrinker *shrinker);
 #endif
index 0494db3..13770cf 100644 (file)
@@ -62,7 +62,7 @@ struct ts_config
        int                     flags;
 
        /**
-        * get_next_block - fetch next block of data
+        * @get_next_block: fetch next block of data
         * @consumed: number of bytes consumed by the caller
         * @dst: destination buffer
         * @conf: search configuration
@@ -79,7 +79,7 @@ struct ts_config
                                                  struct ts_state *state);
 
        /**
-        * finish - finalize/clean a series of get_next_block() calls
+        * @finish: finalize/clean a series of get_next_block() calls
         * @conf: search configuration
         * @state: search state
         *
index 34f053a..cf2862b 100644 (file)
@@ -43,11 +43,7 @@ enum {
 #define THREAD_ALIGN   THREAD_SIZE
 #endif
 
-#if IS_ENABLED(CONFIG_DEBUG_STACK_USAGE) || IS_ENABLED(CONFIG_DEBUG_KMEMLEAK)
-# define THREADINFO_GFP                (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
-#else
-# define THREADINFO_GFP                (GFP_KERNEL_ACCOUNT)
-#endif
+#define THREADINFO_GFP         (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
 
 /*
  * flag set/clear/test wrappers
index af4114d..3616b4b 100644 (file)
@@ -9,9 +9,6 @@
 extern void do_gettimeofday(struct timeval *tv);
 unsigned long get_seconds(void);
 
-/* does not take xtime_lock */
-struct timespec __current_kernel_time(void);
-
 static inline struct timespec current_kernel_time(void)
 {
        struct timespec64 now = current_kernel_time64();
index 2448f9c..7b066fd 100644 (file)
@@ -8,8 +8,6 @@
 #include <linux/debugobjects.h>
 #include <linux/stringify.h>
 
-struct tvec_base;
-
 struct timer_list {
        /*
         * All fields that change during normal runtime grouped to the
index 912b85b..b8e288a 100644 (file)
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {
 #define PERF_RECORD_MISC_COMM_EXEC             (1 << 13)
 #define PERF_RECORD_MISC_SWITCH_OUT            (1 << 13)
 /*
- * Indicates that the content of PERF_SAMPLE_IP points to
- * the actual instruction that triggered the event. See also
- * perf_event_attr::precise_ip.
+ * These PERF_RECORD_MISC_* flags below are safely reused
+ * for the following events:
+ *
+ *   PERF_RECORD_MISC_EXACT_IP           - PERF_RECORD_SAMPLE of precise events
+ *   PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
+ *
+ *
+ * PERF_RECORD_MISC_EXACT_IP:
+ *   Indicates that the content of PERF_SAMPLE_IP points to
+ *   the actual instruction that triggered the event. See also
+ *   perf_event_attr::precise_ip.
+ *
+ * PERF_RECORD_MISC_SWITCH_OUT_PREEMPT:
+ *   Indicates that thread was preempted in TASK_RUNNING state.
  */
 #define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT    (1 << 14)
 /*
  * Reserve the last bit to indicate some extended misc field
  */
index c34f449..26ee913 100644 (file)
@@ -35,6 +35,9 @@
 /* Clear the entropy pool and associated counters.  (Superuser only.) */
 #define RNDCLEARPOOL   _IO( 'R', 0x06 )
 
+/* Reseed CRNG.  (Superuser only.) */
+#define RNDRESEEDCRNG  _IO( 'R', 0x07 )
+
 struct rand_pool_info {
        int     entropy_count;
        int     buf_size;
index 5c91827..78bb5d9 100644 (file)
 #include "ring.h"
 #include "../grant_table.h"
 
+/*
+ ******************************************************************************
+ *                           Protocol version
+ ******************************************************************************
+ */
+#define XENSND_PROTOCOL_VERSION        2
+
 /*
  ******************************************************************************
  *                  Feature and Parameter Negotiation
  *
  * /local/domain/1/device/vsnd/0/0/0/ring-ref = "386"
  * /local/domain/1/device/vsnd/0/0/0/event-channel = "15"
+ * /local/domain/1/device/vsnd/0/0/0/evt-ring-ref = "1386"
+ * /local/domain/1/device/vsnd/0/0/0/evt-event-channel = "215"
  *
  *------------------------------ Stream 1, capture ----------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/0/1/ring-ref = "384"
  * /local/domain/1/device/vsnd/0/0/1/event-channel = "13"
+ * /local/domain/1/device/vsnd/0/0/1/evt-ring-ref = "1384"
+ * /local/domain/1/device/vsnd/0/0/1/evt-event-channel = "213"
  *
  *------------------------------- PCM device 1 --------------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/1/0/ring-ref = "387"
  * /local/domain/1/device/vsnd/0/1/0/event-channel = "151"
+ * /local/domain/1/device/vsnd/0/1/0/evt-ring-ref = "1387"
+ * /local/domain/1/device/vsnd/0/1/0/evt-event-channel = "351"
  *
  *------------------------------- PCM device 2 --------------------------------
  *
  *
  * /local/domain/1/device/vsnd/0/2/0/ring-ref = "389"
  * /local/domain/1/device/vsnd/0/2/0/event-channel = "152"
+ * /local/domain/1/device/vsnd/0/2/0/evt-ring-ref = "1389"
+ * /local/domain/1/device/vsnd/0/2/0/evt-event-channel = "452"
  *
  ******************************************************************************
  *                            Backend XenBus Nodes
  *      The Xen grant reference granting permission for the backend to map
  *      a sole page in a single page sized ring buffer.
  *
+ *--------------------- Stream Event Transport Parameters ---------------------
+ *
+ * This communication path is used to deliver asynchronous events from backend
+ * to frontend, set up per stream.
+ *
+ * evt-event-channel
+ *      Values:         <uint32_t>
+ *
+ *      The identifier of the Xen event channel used to signal activity
+ *      in the ring buffer.
+ *
+ * evt-ring-ref
+ *      Values:         <uint32_t>
+ *
+ *      The Xen grant reference granting permission for the backend to map
+ *      a sole page in a single page sized ring buffer.
+ *
  ******************************************************************************
  *                               STATE DIAGRAMS
  ******************************************************************************
 #define XENSND_OP_GET_VOLUME           5
 #define XENSND_OP_MUTE                 6
 #define XENSND_OP_UNMUTE               7
+#define XENSND_OP_TRIGGER              8
+#define XENSND_OP_HW_PARAM_QUERY       9
+
+#define XENSND_OP_TRIGGER_START                0
+#define XENSND_OP_TRIGGER_PAUSE                1
+#define XENSND_OP_TRIGGER_STOP         2
+#define XENSND_OP_TRIGGER_RESUME       3
+
+/*
+ ******************************************************************************
+ *                                 EVENT CODES
+ ******************************************************************************
+ */
+#define XENSND_EVT_CUR_POS             0
 
 /*
  ******************************************************************************
 #define XENSND_FIELD_VCARD_LONG_NAME   "long-name"
 #define XENSND_FIELD_RING_REF          "ring-ref"
 #define XENSND_FIELD_EVT_CHNL          "event-channel"
+#define XENSND_FIELD_EVT_RING_REF      "evt-ring-ref"
+#define XENSND_FIELD_EVT_EVT_CHNL      "evt-event-channel"
 #define XENSND_FIELD_DEVICE_NAME       "name"
 #define XENSND_FIELD_TYPE              "type"
 #define XENSND_FIELD_STREAM_UNIQUE_ID  "unique-id"
  *
  *---------------------------------- Requests ---------------------------------
  *
- * All request packets have the same length (32 octets)
+ * All request packets have the same length (64 octets)
  * All request packets have common header:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
  * +----------------+----------------+----------------+----------------+
  * |                           gref_directory                          | 24
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 28
+ * |                             period_sz                             | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 32
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * pcm_rate - uint32_t, stream data rate, Hz
  * pcm_channels - uint8_t, number of channels of this stream,
  *   [channels-min; channels-max]
  * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * period_sz - uint32_t, event period size, octets
+ *   This is the requested value of the period at which frontend would
+ *   like to receive XENSND_EVT_CUR_POS notifications from the backend when
+ *   stream position advances during playback/capture.
+ *   It shows how many octets are expected to be played/captured before
+ *   sending such an event.
+ *   If set to 0 no XENSND_EVT_CUR_POS events are sent by the backend.
+ *
  * gref_directory - grant_ref_t, a reference to the first shared page
  *   describing shared buffer references. At least one page exists. If shared
  *   buffer size  (buffer_sz) exceeds what can be addressed by this single page,
@@ -585,6 +643,7 @@ struct xensnd_open_req {
        uint16_t reserved;
        uint32_t buffer_sz;
        grant_ref_t gref_directory;
+       uint32_t period_sz;
 };
 
 /*
@@ -632,7 +691,7 @@ struct xensnd_page_directory {
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * Request read/write - used for read (for capture) or write (for playback):
@@ -650,7 +709,7 @@ struct xensnd_page_directory {
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_READ for read or XENSND_OP_WRITE for write
@@ -673,9 +732,11 @@ struct xensnd_rw_req {
  * +----------------+----------------+----------------+----------------+
  * |                              length                               | 16
  * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_SET_VOLUME for volume set
@@ -713,9 +774,11 @@ struct xensnd_rw_req {
  * +----------------+----------------+----------------+----------------+
  * |                              length                               | 16
  * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
  * +----------------+----------------+----------------+----------------+
  *
  * operation - XENSND_OP_MUTE for mute or XENSND_OP_UNMUTE for unmute
@@ -743,32 +806,213 @@ struct xensnd_rw_req {
  *
  * The 'struct xensnd_rw_req' is also used for XENSND_OP_SET_VOLUME,
  * XENSND_OP_GET_VOLUME, XENSND_OP_MUTE, XENSND_OP_UNMUTE.
+ *
+ * Request stream running state change - trigger PCM stream running state
+ * to start, stop, pause or resume:
+ *
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _OP_TRIGGER  |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |      type      |                     reserved                     | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * type - uint8_t, XENSND_OP_TRIGGER_XXX value
  */
 
+struct xensnd_trigger_req {
+       uint8_t type;
+};
+
 /*
- *---------------------------------- Responses --------------------------------
+ * Request stream parameter ranges: request intervals and
+ *   masks of supported ranges for stream configuration values.
  *
- * All response packets have the same length (32 octets)
+ *   Sound device configuration for a particular stream is a limited subset
+ *   of the multidimensional configuration available on XenStore, e.g.
+ *   once the frame rate has been selected there is a limited supported range
+ *   for sample rates becomes available (which might be the same set configured
+ *   on XenStore or less). For example, selecting 96kHz sample rate may limit
+ *   number of channels available for such configuration from 4 to 2, etc.
+ *   Thus, each call to XENSND_OP_HW_PARAM_QUERY may reduce configuration
+ *   space making it possible to iteratively get the final stream configuration,
+ *   used in XENSND_OP_OPEN request.
+ *
+ *   See response format for this request.
  *
- * Response for all requests:
  *         0                1                 2               3        octet
  * +----------------+----------------+----------------+----------------+
- * |               id                |    operation   |    reserved    | 4
+ * |               id                | _HW_PARAM_QUERY|    reserved    | 4
  * +----------------+----------------+----------------+----------------+
- * |                              status                               | 8
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask high 32-bit                      | 16
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 12
+ * |                              min rate                             | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                              max rate                             | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                            min channels                           | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                            max channels                           | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                         min buffer frames                         | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                         max buffer frames                         | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                         min period frames                         | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                         max period frames                         | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 52
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 32
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * formats - uint64_t, bit mask representing values of the parameter
+ *     made as bitwise OR of (1 << XENSND_PCM_FORMAT_XXX) values
+ *
+ * For interval parameters:
+ *   min - uint32_t, minimum value of the parameter
+ *   max - uint32_t, maximum value of the parameter
+ *
+ * Frame is defined as a product of the number of channels by the
+ * number of octets per one sample.
+ */
+
+struct xensnd_query_hw_param {
+       uint64_t formats;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } rates;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } channels;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } buffer;
+       struct {
+               uint32_t min;
+               uint32_t max;
+       } period;
+};
+
+/*
+ *---------------------------------- Responses --------------------------------
+ *
+ * All response packets have the same length (64 octets)
+ *
+ * All response packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
  * +----------------+----------------+----------------+----------------+
  *
  * id - uint16_t, copied from the request
  * operation - uint8_t, XENSND_OP_* - copied from request
  * status - int32_t, response status, zero on success and -XEN_EXX on failure
+ *
+ *
+ * HW parameter query response - response for XENSND_OP_HW_PARAM_QUERY:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                     formats mask high 32-bit                      | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                              min rate                             | 20
+ * +----------------+----------------+----------------+----------------+
+ * |                              max rate                             | 24
+ * +----------------+----------------+----------------+----------------+
+ * |                            min channels                           | 28
+ * +----------------+----------------+----------------+----------------+
+ * |                            max channels                           | 32
+ * +----------------+----------------+----------------+----------------+
+ * |                         min buffer frames                         | 36
+ * +----------------+----------------+----------------+----------------+
+ * |                         max buffer frames                         | 40
+ * +----------------+----------------+----------------+----------------+
+ * |                         min period frames                         | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                         max period frames                         | 48
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 52
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Meaning of the values in this response is the same as for
+ * XENSND_OP_HW_PARAM_QUERY request.
+ */
+
+/*
+ *----------------------------------- Events ----------------------------------
+ *
+ * Events are sent via shared page allocated by the front and propagated by
+ *   evt-event-channel/evt-ring-ref XenStore entries
+ * All event packets have the same length (64 octets)
+ * All event packets have common header:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |      type      |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ *
+ * id - uint16_t, event id, may be used by front
+ * type - uint8_t, type of the event
+ *
+ *
+ * Current stream position - event from back to front when stream's
+ *   playback/capture position has advanced:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |   _EVT_CUR_POS |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                         position low 32-bit                       | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                         position high 32-bit                      | 16
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 20
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * position - current value of stream's playback/capture position, octets
+ *
  */
 
+struct xensnd_cur_pos_evt {
+       uint64_t position;
+};
+
 struct xensnd_req {
        uint16_t id;
        uint8_t operation;
@@ -776,7 +1020,9 @@ struct xensnd_req {
        union {
                struct xensnd_open_req open;
                struct xensnd_rw_req rw;
-               uint8_t reserved[24];
+               struct xensnd_trigger_req trigger;
+               struct xensnd_query_hw_param hw_param;
+               uint8_t reserved[56];
        } op;
 };
 
@@ -785,9 +1031,53 @@ struct xensnd_resp {
        uint8_t operation;
        uint8_t reserved;
        int32_t status;
-       uint8_t reserved1[24];
+       union {
+               struct xensnd_query_hw_param hw_param;
+               uint8_t reserved1[56];
+       } resp;
+};
+
+struct xensnd_evt {
+       uint16_t id;
+       uint8_t type;
+       uint8_t reserved[5];
+       union {
+               struct xensnd_cur_pos_evt cur_pos;
+               uint8_t reserved[56];
+       } op;
 };
 
 DEFINE_RING_TYPES(xen_sndif, struct xensnd_req, struct xensnd_resp);
 
+/*
+ ******************************************************************************
+ *                        Back to front events delivery
+ ******************************************************************************
+ * In order to deliver asynchronous events from back to front a shared page is
+ * allocated by front and its granted reference propagated to back via
+ * XenStore entries (evt-ring-ref/evt-event-channel).
+ * This page has a common header used by both front and back to synchronize
+ * access and control event's ring buffer, while back being a producer of the
+ * events and front being a consumer. The rest of the page after the header
+ * is used for event packets.
+ *
+ * Upon reception of an event(s) front may confirm its reception
+ * for either each event, group of events or none.
+ */
+
+struct xensnd_event_page {
+       uint32_t in_cons;
+       uint32_t in_prod;
+       uint8_t reserved[56];
+};
+
+#define XENSND_EVENT_PAGE_SIZE XEN_PAGE_SIZE
+#define XENSND_IN_RING_OFFS (sizeof(struct xensnd_event_page))
+#define XENSND_IN_RING_SIZE (XENSND_EVENT_PAGE_SIZE - XENSND_IN_RING_OFFS)
+#define XENSND_IN_RING_LEN (XENSND_IN_RING_SIZE / sizeof(struct xensnd_evt))
+#define XENSND_IN_RING(page) \
+       ((struct xensnd_evt *)((char *)(page) + XENSND_IN_RING_OFFS))
+#define XENSND_IN_RING_REF(page, idx) \
+       (XENSND_IN_RING((page))[(idx) % XENSND_IN_RING_LEN])
+
 #endif /* __XEN_PUBLIC_IO_SNDIF_H__ */
index 772a43f..c187aa3 100644 (file)
@@ -119,23 +119,20 @@ int get_callchain_buffers(int event_max_stack)
                goto exit;
        }
 
-       if (count > 1) {
-               /* If the allocation failed, give up */
-               if (!callchain_cpus_entries)
-                       err = -ENOMEM;
-               /*
-                * If requesting per event more than the global cap,
-                * return a different error to help userspace figure
-                * this out.
-                *
-                * And also do it here so that we have &callchain_mutex held.
-                */
-               if (event_max_stack > sysctl_perf_event_max_stack)
-                       err = -EOVERFLOW;
+       /*
+        * If requesting per event more than the global cap,
+        * return a different error to help userspace figure
+        * this out.
+        *
+        * And also do it here so that we have &callchain_mutex held.
+        */
+       if (event_max_stack > sysctl_perf_event_max_stack) {
+               err = -EOVERFLOW;
                goto exit;
        }
 
-       err = alloc_callchain_buffers();
+       if (count == 1)
+               err = alloc_callchain_buffers();
 exit:
        if (err)
                atomic_dec(&nr_callchain_events);
index 2d5fe26..67612ce 100644 (file)
@@ -7587,6 +7587,10 @@ static void perf_event_switch(struct task_struct *task,
                },
        };
 
+       if (!sched_in && task->state == TASK_RUNNING)
+               switch_event.event_id.header.misc |=
+                               PERF_RECORD_MISC_SWITCH_OUT_PREEMPT;
+
        perf_iterate_sb(perf_event_switch_output,
                       &switch_event,
                       NULL);
@@ -10205,9 +10209,9 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
                 * __u16 sample size limit.
                 */
                if (attr->sample_stack_user >= USHRT_MAX)
-                       ret = -EINVAL;
+                       return -EINVAL;
                else if (!IS_ALIGNED(attr->sample_stack_user, sizeof(u64)))
-                       ret = -EINVAL;
+                       return -EINVAL;
        }
 
        if (!attr->sample_max_stack)
index 242c8c9..a5d21c4 100644 (file)
@@ -216,10 +216,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
                if (!s)
                        continue;
 
-#ifdef CONFIG_DEBUG_KMEMLEAK
                /* Clear stale pointers from reused stack. */
                memset(s->addr, 0, THREAD_SIZE);
-#endif
+
                tsk->stack_vm_area = s;
                return s->addr;
        }
index fdac275..83958c8 100644 (file)
@@ -113,8 +113,10 @@ void *klp_shadow_get(void *obj, unsigned long id)
 }
 EXPORT_SYMBOL_GPL(klp_shadow_get);
 
-static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags, bool warn_on_exist)
+static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                                      size_t size, gfp_t gfp_flags,
+                                      klp_shadow_ctor_t ctor, void *ctor_data,
+                                      bool warn_on_exist)
 {
        struct klp_shadow *new_shadow;
        void *shadow_data;
@@ -125,18 +127,15 @@ static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
        if (shadow_data)
                goto exists;
 
-       /* Allocate a new shadow variable for use inside the lock below */
+       /*
+        * Allocate a new shadow variable.  Fill it with zeroes by default.
+        * More complex setting can be done by @ctor function.  But it is
+        * called only when the buffer is really used (under klp_shadow_lock).
+        */
        new_shadow = kzalloc(size + sizeof(*new_shadow), gfp_flags);
        if (!new_shadow)
                return NULL;
 
-       new_shadow->obj = obj;
-       new_shadow->id = id;
-
-       /* Initialize the shadow variable if data provided */
-       if (data)
-               memcpy(new_shadow->data, data, size);
-
        /* Look for <obj, id> again under the lock */
        spin_lock_irqsave(&klp_shadow_lock, flags);
        shadow_data = klp_shadow_get(obj, id);
@@ -150,6 +149,22 @@ static void *__klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
                goto exists;
        }
 
+       new_shadow->obj = obj;
+       new_shadow->id = id;
+
+       if (ctor) {
+               int err;
+
+               err = ctor(obj, new_shadow->data, ctor_data);
+               if (err) {
+                       spin_unlock_irqrestore(&klp_shadow_lock, flags);
+                       kfree(new_shadow);
+                       pr_err("Failed to construct shadow variable <%p, %lx> (%d)\n",
+                              obj, id, err);
+                       return NULL;
+               }
+       }
+
        /* No <obj, id> found, so attach the newly allocated one */
        hash_add_rcu(klp_shadow_hash, &new_shadow->node,
                     (unsigned long)new_shadow->obj);
@@ -170,26 +185,32 @@ exists:
  * klp_shadow_alloc() - allocate and add a new shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
- * @data:      pointer to data to attach to parent
  * @size:      size of attached data
  * @gfp_flags: GFP mask for allocation
+ * @ctor:      custom constructor to initialize the shadow data (optional)
+ * @ctor_data: pointer to any data needed by @ctor (optional)
+ *
+ * Allocates @size bytes for new shadow variable data using @gfp_flags.
+ * The data are zeroed by default.  They are further initialized by @ctor
+ * function if it is not NULL.  The new shadow variable is then added
+ * to the global hashtable.
  *
- * Allocates @size bytes for new shadow variable data using @gfp_flags
- * and copies @size bytes from @data into the new shadow variable's own
- * data space.  If @data is NULL, @size bytes are still allocated, but
- * no copy is performed.  The new shadow variable is then added to the
- * global hashtable.
+ * If an existing <obj, id> shadow variable can be found, this routine will
+ * issue a WARN, exit early and return NULL.
  *
- * If an existing <obj, id> shadow variable can be found, this routine
- * will issue a WARN, exit early and return NULL.
+ * This function guarantees that the constructor function is called only when
+ * the variable did not exist before.  The cost is that @ctor is called
+ * in atomic context under a spin lock.
  *
  * Return: the shadow variable data element, NULL on duplicate or
  * failure.
  */
-void *klp_shadow_alloc(void *obj, unsigned long id, void *data,
-                      size_t size, gfp_t gfp_flags)
+void *klp_shadow_alloc(void *obj, unsigned long id,
+                      size_t size, gfp_t gfp_flags,
+                      klp_shadow_ctor_t ctor, void *ctor_data)
 {
-       return __klp_shadow_get_or_alloc(obj, id, data, size, gfp_flags, true);
+       return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags,
+                                        ctor, ctor_data, true);
 }
 EXPORT_SYMBOL_GPL(klp_shadow_alloc);
 
@@ -197,37 +218,51 @@ EXPORT_SYMBOL_GPL(klp_shadow_alloc);
  * klp_shadow_get_or_alloc() - get existing or allocate a new shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
- * @data:      pointer to data to attach to parent
  * @size:      size of attached data
  * @gfp_flags: GFP mask for allocation
+ * @ctor:      custom constructor to initialize the shadow data (optional)
+ * @ctor_data: pointer to any data needed by @ctor (optional)
  *
  * Returns a pointer to existing shadow data if an <obj, id> shadow
  * variable is already present.  Otherwise, it creates a new shadow
  * variable like klp_shadow_alloc().
  *
- * This function guarantees that only one shadow variable exists with
- * the given @id for the given @obj.  It also guarantees that the shadow
- * variable will be initialized by the given @data only when it did not
- * exist before.
+ * This function guarantees that only one shadow variable exists with the given
+ * @id for the given @obj.  It also guarantees that the constructor function
+ * will be called only when the variable did not exist before.  The cost is
+ * that @ctor is called in atomic context under a spin lock.
  *
  * Return: the shadow variable data element, NULL on failure.
  */
-void *klp_shadow_get_or_alloc(void *obj, unsigned long id, void *data,
-                              size_t size, gfp_t gfp_flags)
+void *klp_shadow_get_or_alloc(void *obj, unsigned long id,
+                             size_t size, gfp_t gfp_flags,
+                             klp_shadow_ctor_t ctor, void *ctor_data)
 {
-       return __klp_shadow_get_or_alloc(obj, id, data, size, gfp_flags, false);
+       return __klp_shadow_get_or_alloc(obj, id, size, gfp_flags,
+                                        ctor, ctor_data, false);
 }
 EXPORT_SYMBOL_GPL(klp_shadow_get_or_alloc);
 
+static void klp_shadow_free_struct(struct klp_shadow *shadow,
+                                  klp_shadow_dtor_t dtor)
+{
+       hash_del_rcu(&shadow->node);
+       if (dtor)
+               dtor(shadow->obj, shadow->data);
+       kfree_rcu(shadow, rcu_head);
+}
+
 /**
  * klp_shadow_free() - detach and free a <obj, id> shadow variable
  * @obj:       pointer to parent object
  * @id:                data identifier
+ * @dtor:      custom callback that can be used to unregister the variable
+ *             and/or free data that the shadow variable points to (optional)
  *
  * This function releases the memory for this <obj, id> shadow variable
  * instance, callers should stop referencing it accordingly.
  */
-void klp_shadow_free(void *obj, unsigned long id)
+void klp_shadow_free(void *obj, unsigned long id, klp_shadow_dtor_t dtor)
 {
        struct klp_shadow *shadow;
        unsigned long flags;
@@ -239,8 +274,7 @@ void klp_shadow_free(void *obj, unsigned long id)
                               (unsigned long)obj) {
 
                if (klp_shadow_match(shadow, obj, id)) {
-                       hash_del_rcu(&shadow->node);
-                       kfree_rcu(shadow, rcu_head);
+                       klp_shadow_free_struct(shadow, dtor);
                        break;
                }
        }
@@ -252,11 +286,13 @@ EXPORT_SYMBOL_GPL(klp_shadow_free);
 /**
  * klp_shadow_free_all() - detach and free all <*, id> shadow variables
  * @id:                data identifier
+ * @dtor:      custom callback that can be used to unregister the variable
+ *             and/or free data that the shadow variable points to (optional)
  *
  * This function releases the memory for all <*, id> shadow variable
  * instances, callers should stop referencing them accordingly.
  */
-void klp_shadow_free_all(unsigned long id)
+void klp_shadow_free_all(unsigned long id, klp_shadow_dtor_t dtor)
 {
        struct klp_shadow *shadow;
        unsigned long flags;
@@ -266,10 +302,8 @@ void klp_shadow_free_all(unsigned long id)
 
        /* Delete all <*, id> from hash */
        hash_for_each(klp_shadow_hash, i, shadow, node) {
-               if (klp_shadow_match(shadow, shadow->obj, id)) {
-                       hash_del_rcu(&shadow->node);
-                       kfree_rcu(shadow, rcu_head);
-               }
+               if (klp_shadow_match(shadow, shadow->obj, id))
+                       klp_shadow_free_struct(shadow, dtor);
        }
 
        spin_unlock_irqrestore(&klp_shadow_lock, flags);
index 2541bd8..5a6251a 100644 (file)
@@ -1205,10 +1205,12 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
                           u64 *newval, u64 *oldval)
 {
        u64 now;
+       int ret;
 
        WARN_ON_ONCE(clock_idx == CPUCLOCK_SCHED);
+       ret = cpu_timer_sample_group(clock_idx, tsk, &now);
 
-       if (oldval && cpu_timer_sample_group(clock_idx, tsk, &now) != -EINVAL) {
+       if (oldval && ret != -EINVAL) {
                /*
                 * We are setting itimer. The *oldval is absolute and we update
                 * it to be relative, *newval argument is relative and we update
index c1f518e..6fe615d 100644 (file)
@@ -82,16 +82,15 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
        if (!dev || !(dev->features & CLOCK_EVT_FEAT_ONESHOT) ||
                    !tick_device_is_functional(dev)) {
 
-               printk(KERN_INFO "Clockevents: "
-                      "could not switch to one-shot mode:");
+               pr_info("Clockevents: could not switch to one-shot mode:");
                if (!dev) {
-                       printk(" no tick device\n");
+                       pr_cont(" no tick device\n");
                } else {
                        if (!tick_device_is_functional(dev))
-                               printk(" %s is not functional.\n", dev->name);
+                               pr_cont(" %s is not functional.\n", dev->name);
                        else
-                               printk(" %s does not support one-shot mode.\n",
-                                      dev->name);
+                               pr_cont(" %s does not support one-shot mode.\n",
+                                       dev->name);
                }
                return -EINVAL;
        }
index ca90219..dcf7f20 100644 (file)
@@ -2139,13 +2139,6 @@ unsigned long get_seconds(void)
 }
 EXPORT_SYMBOL(get_seconds);
 
-struct timespec __current_kernel_time(void)
-{
-       struct timekeeper *tk = &tk_core.timekeeper;
-
-       return timespec64_to_timespec(tk_xtime(tk));
-}
-
 struct timespec64 current_kernel_time64(void)
 {
        struct timekeeper *tk = &tk_core.timekeeper;
index 1cd3fb4..02aed76 100644 (file)
@@ -512,8 +512,6 @@ static int __register_trace_kprobe(struct trace_kprobe *tk)
        if (ret == 0)
                tk->tp.flags |= TP_FLAG_REGISTERED;
        else {
-               pr_warn("Could not insert probe at %s+%lu: %d\n",
-                       trace_kprobe_symbol(tk), trace_kprobe_offset(tk), ret);
                if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) {
                        pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
                        ret = 0;
index 0b79908..5939549 100644 (file)
  *             Pablo Neira Ayuso <pablo@netfilter.org>
  *
  * ==========================================================================
- *
+ */
+
+/**
+ * DOC: ts_intro
  * INTRODUCTION
  *
  *   The textsearch infrastructure provides text searching facilities for
@@ -19,7 +22,9 @@
  *
  * ARCHITECTURE
  *
- *      User
+ * .. code-block:: none
+ *
+ *     User
  *     +----------------+
  *     |        finish()|<--------------(6)-----------------+
  *     |get_next_block()|<--------------(5)---------------+ |
  *     |             (3)|----->| find()/next() |-----------+          |
  *     |             (7)|----->| destroy()     |----------------------+
  *     +----------------+      +---------------+
- *  
- *   (1) User configures a search by calling _prepare() specifying the
- *       search parameters such as the pattern and algorithm name.
+ *
+ *   (1) User configures a search by calling textsearch_prepare() specifying
+ *       the search parameters such as the pattern and algorithm name.
  *   (2) Core requests the algorithm to allocate and initialize a search
  *       configuration according to the specified parameters.
- *   (3) User starts the search(es) by calling _find() or _next() to
- *       fetch subsequent occurrences. A state variable is provided
- *       to the algorithm to store persistent variables.
+ *   (3) User starts the search(es) by calling textsearch_find() or
+ *       textsearch_next() to fetch subsequent occurrences. A state variable
+ *       is provided to the algorithm to store persistent variables.
  *   (4) Core eventually resets the search offset and forwards the find()
  *       request to the algorithm.
  *   (5) Algorithm calls get_next_block() provided by the user continuously
  *       to fetch the data to be searched in block by block.
  *   (6) Algorithm invokes finish() after the last call to get_next_block
  *       to clean up any leftovers from get_next_block. (Optional)
- *   (7) User destroys the configuration by calling _destroy().
+ *   (7) User destroys the configuration by calling textsearch_destroy().
  *   (8) Core notifies the algorithm to destroy algorithm specific
  *       allocations. (Optional)
  *
  *   amount of times and even in parallel as long as a separate struct
  *   ts_state variable is provided to every instance.
  *
- *   The actual search is performed by either calling textsearch_find_-
- *   continuous() for linear data or by providing an own get_next_block()
- *   implementation and calling textsearch_find(). Both functions return
+ *   The actual search is performed by either calling
+ *   textsearch_find_continuous() for linear data or by providing
+ *   an own get_next_block() implementation and
+ *   calling textsearch_find(). Both functions return
  *   the position of the first occurrence of the pattern or UINT_MAX if
  *   no match was found. Subsequent occurrences can be found by calling
  *   textsearch_next() regardless of the linearity of the data.
@@ -72,7 +78,7 @@
  *   Once you're done using a configuration it must be given back via
  *   textsearch_destroy.
  *
- * EXAMPLE
+ * EXAMPLE::
  *
  *   int pos;
  *   struct ts_config *conf;
  *       goto errout;
  *   }
  *
- *   pos = textsearch_find_continuous(conf, &state, example, strlen(example));
+ *   pos = textsearch_find_continuous(conf, \&state, example, strlen(example));
  *   if (pos != UINT_MAX)
- *       panic("Oh my god, dancing chickens at %d\n", pos);
+ *       panic("Oh my god, dancing chickens at \%d\n", pos);
  *
  *   textsearch_destroy(conf);
- * ==========================================================================
  */
+/* ========================================================================== */
 
 #include <linux/module.h>
 #include <linux/types.h>
@@ -225,7 +231,7 @@ static unsigned int get_linear_data(unsigned int consumed, const u8 **dst,
  *
  * Returns the position of first occurrence of the pattern or
  * %UINT_MAX if no occurrence was found.
- */ 
+ */
 unsigned int textsearch_find_continuous(struct ts_config *conf,
                                        struct ts_state *state,
                                        const void *data, unsigned int len)
index 9276bdb..0604cb0 100644 (file)
@@ -786,7 +786,7 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
        VM_BUG_ON_PAGE(!PageLocked(new), new);
        VM_BUG_ON_PAGE(new->mapping, new);
 
-       error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
+       error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK);
        if (!error) {
                struct address_space *mapping = old->mapping;
                void (*freepage)(struct page *);
@@ -842,7 +842,7 @@ static int __add_to_page_cache_locked(struct page *page,
                        return error;
        }
 
-       error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM);
+       error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK);
        if (error) {
                if (!huge)
                        mem_cgroup_cancel_charge(page, memcg, false);
@@ -1585,8 +1585,7 @@ no_page:
                if (fgp_flags & FGP_ACCESSED)
                        __SetPageReferenced(page);
 
-               err = add_to_page_cache_lru(page, mapping, offset,
-                               gfp_mask & GFP_RECLAIM_MASK);
+               err = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
                if (unlikely(err)) {
                        put_page(page);
                        page = NULL;
@@ -2387,7 +2386,7 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask)
                if (!page)
                        return -ENOMEM;
 
-               ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL);
+               ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
                if (ret == 0)
                        ret = mapping->a_ops->readpage(file, page);
                else if (ret == -EEXIST)
index 3e8cda7..323acdd 100644 (file)
@@ -2925,7 +2925,10 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new)
                pmde = maybe_pmd_mkwrite(pmde, vma);
 
        flush_cache_range(vma, mmun_start, mmun_start + HPAGE_PMD_SIZE);
-       page_add_anon_rmap(new, vma, mmun_start, true);
+       if (PageAnon(new))
+               page_add_anon_rmap(new, vma, mmun_start, true);
+       else
+               page_add_file_rmap(new, true);
        set_pmd_at(mm, mmun_start, pvmw->pmd, pmde);
        if (vma->vm_flags & VM_LOCKED)
                mlock_vma_page(new);
index e074f7c..2bd3df3 100644 (file)
@@ -2192,7 +2192,7 @@ static void __memcg_schedule_kmem_cache_create(struct mem_cgroup *memcg,
 {
        struct memcg_kmem_cache_create_work *cw;
 
-       cw = kmalloc(sizeof(*cw), GFP_NOWAIT);
+       cw = kmalloc(sizeof(*cw), GFP_NOWAIT | __GFP_NOWARN);
        if (!cw)
                return;
 
index f65dd69..5684330 100644 (file)
@@ -472,7 +472,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
        pslot = radix_tree_lookup_slot(&mapping->i_pages,
                                        page_index(page));
 
-       expected_count += 1 + page_has_private(page);
+       expected_count += hpage_nr_pages(page) + page_has_private(page);
        if (page_count(page) != expected_count ||
                radix_tree_deref_slot_protected(pslot,
                                        &mapping->i_pages.xa_lock) != page) {
@@ -505,7 +505,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
         */
        newpage->index = page->index;
        newpage->mapping = page->mapping;
-       get_page(newpage);      /* add cache reference */
+       page_ref_add(newpage, hpage_nr_pages(page)); /* add cache reference */
        if (PageSwapBacked(page)) {
                __SetPageSwapBacked(newpage);
                if (PageSwapCache(page)) {
@@ -524,13 +524,26 @@ int migrate_page_move_mapping(struct address_space *mapping,
        }
 
        radix_tree_replace_slot(&mapping->i_pages, pslot, newpage);
+       if (PageTransHuge(page)) {
+               int i;
+               int index = page_index(page);
+
+               for (i = 0; i < HPAGE_PMD_NR; i++) {
+                       pslot = radix_tree_lookup_slot(&mapping->i_pages,
+                                                      index + i);
+                       radix_tree_replace_slot(&mapping->i_pages, pslot,
+                                               newpage + i);
+               }
+       } else {
+               radix_tree_replace_slot(&mapping->i_pages, pslot, newpage);
+       }
 
        /*
         * Drop cache reference from old page by unfreezing
         * to one less reference.
         * We know this isn't the last reference.
         */
-       page_ref_unfreeze(page, expected_count - 1);
+       page_ref_unfreeze(page, expected_count - hpage_nr_pages(page));
 
        xa_unlock(&mapping->i_pages);
        /* Leave irq disabled to prevent preemption while updating stats */
@@ -1622,6 +1635,9 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
                current_node = NUMA_NO_NODE;
        }
 out_flush:
+       if (list_empty(&pagelist))
+               return err;
+
        /* Make sure we do not overwrite the existing error */
        err1 = do_move_pages_to_node(mm, &pagelist, current_node);
        if (!err1)
index 5c1a327..337c6af 100644 (file)
@@ -2502,13 +2502,13 @@ void account_page_redirty(struct page *page)
        if (mapping && mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
                current->nr_dirtied--;
                dec_node_page_state(page, NR_DIRTIED);
                dec_wb_stat(wb, WB_DIRTIED);
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
        }
 }
 EXPORT_SYMBOL(account_page_redirty);
@@ -2614,15 +2614,15 @@ void __cancel_dirty_page(struct page *page)
        if (mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
                lock_page_memcg(page);
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
 
                if (TestClearPageDirty(page))
                        account_page_cleaned(page, mapping, wb);
 
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
                unlock_page_memcg(page);
        } else {
                ClearPageDirty(page);
@@ -2654,7 +2654,7 @@ int clear_page_dirty_for_io(struct page *page)
        if (mapping && mapping_cap_account_dirty(mapping)) {
                struct inode *inode = mapping->host;
                struct bdi_writeback *wb;
-               bool locked;
+               struct wb_lock_cookie cookie = {};
 
                /*
                 * Yes, Virginia, this is indeed insane.
@@ -2691,14 +2691,14 @@ int clear_page_dirty_for_io(struct page *page)
                 * always locked coming in here, so we get the desired
                 * exclusion.
                 */
-               wb = unlocked_inode_to_wb_begin(inode, &locked);
+               wb = unlocked_inode_to_wb_begin(inode, &cookie);
                if (TestClearPageDirty(page)) {
                        dec_lruvec_page_state(page, NR_FILE_DIRTY);
                        dec_zone_page_state(page, NR_ZONE_WRITE_PENDING);
                        dec_wb_stat(wb, WB_RECLAIMABLE);
                        ret = 1;
                }
-               unlocked_inode_to_wb_end(inode, locked);
+               unlocked_inode_to_wb_end(inode, &cookie);
                return ret;
        }
        return TestClearPageDirty(page);
index 0562133..6db729d 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1374,9 +1374,6 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
                if (!pvmw.pte && (flags & TTU_MIGRATION)) {
                        VM_BUG_ON_PAGE(PageHuge(page) || !PageTransCompound(page), page);
 
-                       if (!PageAnon(page))
-                               continue;
-
                        set_pmd_migration_entry(&pvmw, page);
                        continue;
                }
index 8b920ce..9b69732 100644 (file)
@@ -303,7 +303,7 @@ unsigned long lruvec_lru_size(struct lruvec *lruvec, enum lru_list lru, int zone
 /*
  * Add a shrinker callback to be called from the vm.
  */
-int register_shrinker(struct shrinker *shrinker)
+int prealloc_shrinker(struct shrinker *shrinker)
 {
        size_t size = sizeof(*shrinker->nr_deferred);
 
@@ -313,10 +313,29 @@ int register_shrinker(struct shrinker *shrinker)
        shrinker->nr_deferred = kzalloc(size, GFP_KERNEL);
        if (!shrinker->nr_deferred)
                return -ENOMEM;
+       return 0;
+}
+
+void free_prealloced_shrinker(struct shrinker *shrinker)
+{
+       kfree(shrinker->nr_deferred);
+       shrinker->nr_deferred = NULL;
+}
 
+void register_shrinker_prepared(struct shrinker *shrinker)
+{
        down_write(&shrinker_rwsem);
        list_add_tail(&shrinker->list, &shrinker_list);
        up_write(&shrinker_rwsem);
+}
+
+int register_shrinker(struct shrinker *shrinker)
+{
+       int err = prealloc_shrinker(shrinker);
+
+       if (err)
+               return err;
+       register_shrinker_prepared(shrinker);
        return 0;
 }
 EXPORT_SYMBOL(register_shrinker);
index 53ecda1..13e2ae6 100644 (file)
@@ -174,7 +174,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow,
                flow == CAIF_CTRLCMD_DEINIT_RSP ? "CLOSE/DEINIT" :
                flow == CAIF_CTRLCMD_INIT_FAIL_RSP ? "OPEN_FAIL" :
                flow == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND ?
-                "REMOTE_SHUTDOWN" : "UKNOWN CTRL COMMAND");
+                "REMOTE_SHUTDOWN" : "UNKNOWN CTRL COMMAND");
 
 
 
index 969462e..af0558b 100644 (file)
@@ -2969,7 +2969,7 @@ netdev_features_t passthru_features_check(struct sk_buff *skb,
 }
 EXPORT_SYMBOL(passthru_features_check);
 
-static netdev_features_t dflt_features_check(const struct sk_buff *skb,
+static netdev_features_t dflt_features_check(struct sk_buff *skb,
                                             struct net_device *dev,
                                             netdev_features_t features)
 {
index e3e6a3e..d884d8f 100644 (file)
@@ -839,7 +839,7 @@ void dev_mc_flush(struct net_device *dev)
 EXPORT_SYMBOL(dev_mc_flush);
 
 /**
- *     dev_mc_flush - Init multicast address list
+ *     dev_mc_init - Init multicast address list
  *     @dev: device
  *
  *     Init multicast address list.
index 7b7a14a..ce51986 100644 (file)
@@ -55,7 +55,8 @@ static void neigh_timer_handler(struct timer_list *t);
 static void __neigh_notify(struct neighbour *n, int type, int flags,
                           u32 pid);
 static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+                                   struct net_device *dev);
 
 #ifdef CONFIG_PROC_FS
 static const struct file_operations neigh_stat_seq_fops;
@@ -291,8 +292,7 @@ int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
 {
        write_lock_bh(&tbl->lock);
        neigh_flush_dev(tbl, dev);
-       pneigh_ifdown(tbl, dev);
-       write_unlock_bh(&tbl->lock);
+       pneigh_ifdown_and_unlock(tbl, dev);
 
        del_timer_sync(&tbl->proxy_timer);
        pneigh_queue_purge(&tbl->proxy_queue);
@@ -681,9 +681,10 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
        return -ENOENT;
 }
 
-static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
+static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
+                                   struct net_device *dev)
 {
-       struct pneigh_entry *n, **np;
+       struct pneigh_entry *n, **np, *freelist = NULL;
        u32 h;
 
        for (h = 0; h <= PNEIGH_HASHMASK; h++) {
@@ -691,16 +692,23 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
                while ((n = *np) != NULL) {
                        if (!dev || n->dev == dev) {
                                *np = n->next;
-                               if (tbl->pdestructor)
-                                       tbl->pdestructor(n);
-                               if (n->dev)
-                                       dev_put(n->dev);
-                               kfree(n);
+                               n->next = freelist;
+                               freelist = n;
                                continue;
                        }
                        np = &n->next;
                }
        }
+       write_unlock_bh(&tbl->lock);
+       while ((n = freelist)) {
+               freelist = n->next;
+               n->next = NULL;
+               if (tbl->pdestructor)
+                       tbl->pdestructor(n);
+               if (n->dev)
+                       dev_put(n->dev);
+               kfree(n);
+       }
        return -ENOENT;
 }
 
@@ -2323,12 +2331,16 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
 
        err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL, NULL);
        if (!err) {
-               if (tb[NDA_IFINDEX])
+               if (tb[NDA_IFINDEX]) {
+                       if (nla_len(tb[NDA_IFINDEX]) != sizeof(u32))
+                               return -EINVAL;
                        filter_idx = nla_get_u32(tb[NDA_IFINDEX]);
-
-               if (tb[NDA_MASTER])
+               }
+               if (tb[NDA_MASTER]) {
+                       if (nla_len(tb[NDA_MASTER]) != sizeof(u32))
+                               return -EINVAL;
                        filter_master_idx = nla_get_u32(tb[NDA_MASTER]);
-
+               }
                if (filter_idx || filter_master_idx)
                        flags |= NLM_F_DUMP_FILTERED;
        }
index 8396705..40c8516 100644 (file)
@@ -91,9 +91,9 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
 
                        next_opt = memchr(opt, '#', end - opt) ?: end;
                        opt_len = next_opt - opt;
-                       if (!opt_len) {
-                               printk(KERN_WARNING
-                                      "Empty option to dns_resolver key\n");
+                       if (opt_len <= 0 || opt_len > 128) {
+                               pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n",
+                                                   opt_len);
                                return -EINVAL;
                        }
 
@@ -127,10 +127,8 @@ dns_resolver_preparse(struct key_preparsed_payload *prep)
                        }
 
                bad_option_value:
-                       printk(KERN_WARNING
-                              "Option '%*.*s' to dns_resolver key:"
-                              " bad/missing value\n",
-                              opt_nlen, opt_nlen, opt);
+                       pr_warn_ratelimited("Option '%*.*s' to dns_resolver key: bad/missing value\n",
+                                           opt_nlen, opt_nlen, opt);
                        return -EINVAL;
                } while (opt = next_opt + 1, opt < end);
        }
index 4c11b81..83c73ba 100644 (file)
@@ -1109,6 +1109,10 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
        struct ip_options_rcu *opt;
        struct rtable *rt;
 
+       rt = *rtp;
+       if (unlikely(!rt))
+               return -EFAULT;
+
        /*
         * setup for corking.
         */
@@ -1124,9 +1128,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
                cork->flags |= IPCORK_OPT;
                cork->addr = ipc->addr;
        }
-       rt = *rtp;
-       if (unlikely(!rt))
-               return -EFAULT;
+
        /*
         * We steal reference to this route, caller should not release it
         */
index bccc4c2..9ce1c72 100644 (file)
@@ -2368,6 +2368,7 @@ void tcp_write_queue_purge(struct sock *sk)
        INIT_LIST_HEAD(&tcp_sk(sk)->tsorted_sent_queue);
        sk_mem_reclaim(sk);
        tcp_clear_all_retrans_hints(tcp_sk(sk));
+       tcp_sk(sk)->packets_out = 0;
 }
 
 int tcp_disconnect(struct sock *sk, int flags)
@@ -2417,7 +2418,6 @@ int tcp_disconnect(struct sock *sk, int flags)
        icsk->icsk_backoff = 0;
        tp->snd_cwnd = 2;
        icsk->icsk_probes_out = 0;
-       tp->packets_out = 0;
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_cnt = 0;
        tp->window_clamp = 0;
@@ -2813,8 +2813,10 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
 #ifdef CONFIG_TCP_MD5SIG
        case TCP_MD5SIG:
        case TCP_MD5SIG_EXT:
-               /* Read the IP->Key mappings from userspace */
-               err = tp->af_specific->md5_parse(sk, optname, optval, optlen);
+               if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))
+                       err = tp->af_specific->md5_parse(sk, optname, optval, optlen);
+               else
+                       err = -EINVAL;
                break;
 #endif
        case TCP_USER_TIMEOUT:
index 0fbd3ee..40261cb 100644 (file)
@@ -183,6 +183,26 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
 
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth)
+{
+       const struct l2tp_net *pn = l2tp_pernet(net);
+       struct l2tp_tunnel *tunnel;
+       int count = 0;
+
+       rcu_read_lock_bh();
+       list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+               if (++count > nth) {
+                       l2tp_tunnel_inc_refcount(tunnel);
+                       rcu_read_unlock_bh();
+                       return tunnel;
+               }
+       }
+       rcu_read_unlock_bh();
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_get_nth);
+
 /* Lookup a session. A new reference is held on the returned session. */
 struct l2tp_session *l2tp_session_get(const struct net *net,
                                      struct l2tp_tunnel *tunnel,
@@ -335,26 +355,6 @@ err_tlock:
 }
 EXPORT_SYMBOL_GPL(l2tp_session_register);
 
-struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth)
-{
-       struct l2tp_net *pn = l2tp_pernet(net);
-       struct l2tp_tunnel *tunnel;
-       int count = 0;
-
-       rcu_read_lock_bh();
-       list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
-               if (++count > nth) {
-                       rcu_read_unlock_bh();
-                       return tunnel;
-               }
-       }
-
-       rcu_read_unlock_bh();
-
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(l2tp_tunnel_find_nth);
-
 /*****************************************************************************
  * Receive data handling
  *****************************************************************************/
index ba33cbe..c199020 100644 (file)
@@ -212,6 +212,8 @@ static inline void *l2tp_session_priv(struct l2tp_session *session)
 }
 
 struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth);
+
 void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
 
 struct l2tp_session *l2tp_session_get(const struct net *net,
@@ -220,7 +222,6 @@ struct l2tp_session *l2tp_session_get(const struct net *net,
 struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth);
 struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
                                                const char *ifname);
-struct l2tp_tunnel *l2tp_tunnel_find_nth(const struct net *net, int nth);
 
 int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id,
                       u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg,
index 72e713d..b8f9d45 100644 (file)
@@ -47,7 +47,11 @@ struct l2tp_dfs_seq_data {
 
 static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd)
 {
-       pd->tunnel = l2tp_tunnel_find_nth(pd->net, pd->tunnel_idx);
+       /* Drop reference taken during previous invocation */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+
+       pd->tunnel = l2tp_tunnel_get_nth(pd->net, pd->tunnel_idx);
        pd->tunnel_idx++;
 }
 
@@ -96,7 +100,14 @@ static void *l2tp_dfs_seq_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void l2tp_dfs_seq_stop(struct seq_file *p, void *v)
 {
-       /* nothing to do */
+       struct l2tp_dfs_seq_data *pd = v;
+
+       if (!pd || pd == SEQ_START_TOKEN)
+               return;
+
+       /* Drop reference taken by last invocation of l2tp_dfs_next_tunnel() */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
 }
 
 static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
index b05dbd9..6616c9f 100644 (file)
@@ -487,14 +487,17 @@ static int l2tp_nl_cmd_tunnel_dump(struct sk_buff *skb, struct netlink_callback
        struct net *net = sock_net(skb->sk);
 
        for (;;) {
-               tunnel = l2tp_tunnel_find_nth(net, ti);
+               tunnel = l2tp_tunnel_get_nth(net, ti);
                if (tunnel == NULL)
                        goto out;
 
                if (l2tp_nl_tunnel_send(skb, NETLINK_CB(cb->skb).portid,
                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0)
+                                       tunnel, L2TP_CMD_TUNNEL_GET) < 0) {
+                       l2tp_tunnel_dec_refcount(tunnel);
                        goto out;
+               }
+               l2tp_tunnel_dec_refcount(tunnel);
 
                ti++;
        }
@@ -848,7 +851,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
 
        for (;;) {
                if (tunnel == NULL) {
-                       tunnel = l2tp_tunnel_find_nth(net, ti);
+                       tunnel = l2tp_tunnel_get_nth(net, ti);
                        if (tunnel == NULL)
                                goto out;
                }
@@ -856,6 +859,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
                session = l2tp_session_get_nth(tunnel, si);
                if (session == NULL) {
                        ti++;
+                       l2tp_tunnel_dec_refcount(tunnel);
                        tunnel = NULL;
                        si = 0;
                        continue;
@@ -865,6 +869,7 @@ static int l2tp_nl_cmd_session_dump(struct sk_buff *skb, struct netlink_callback
                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
                                         session, L2TP_CMD_SESSION_GET) < 0) {
                        l2tp_session_dec_refcount(session);
+                       l2tp_tunnel_dec_refcount(tunnel);
                        break;
                }
                l2tp_session_dec_refcount(session);
index 896bbca..7d0c963 100644 (file)
@@ -1551,16 +1551,19 @@ struct pppol2tp_seq_data {
 
 static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
 {
+       /* Drop reference taken during previous invocation */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
+
        for (;;) {
-               pd->tunnel = l2tp_tunnel_find_nth(net, pd->tunnel_idx);
+               pd->tunnel = l2tp_tunnel_get_nth(net, pd->tunnel_idx);
                pd->tunnel_idx++;
 
-               if (pd->tunnel == NULL)
-                       break;
+               /* Only accept L2TPv2 tunnels */
+               if (!pd->tunnel || pd->tunnel->version == 2)
+                       return;
 
-               /* Ignore L2TPv3 tunnels */
-               if (pd->tunnel->version < 3)
-                       break;
+               l2tp_tunnel_dec_refcount(pd->tunnel);
        }
 }
 
@@ -1609,7 +1612,14 @@ static void *pppol2tp_seq_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void pppol2tp_seq_stop(struct seq_file *p, void *v)
 {
-       /* nothing to do */
+       struct pppol2tp_seq_data *pd = v;
+
+       if (!pd || pd == SEQ_START_TOKEN)
+               return;
+
+       /* Drop reference taken by last invocation of pppol2tp_next_tunnel() */
+       if (pd->tunnel)
+               l2tp_tunnel_dec_refcount(pd->tunnel);
 }
 
 static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
index 01dcc08..6d29b2b 100644 (file)
@@ -189,6 +189,7 @@ static int llc_ui_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
        struct llc_sock *llc;
+       struct llc_sap *sap;
 
        if (unlikely(sk == NULL))
                goto out;
@@ -199,9 +200,15 @@ static int llc_ui_release(struct socket *sock)
                llc->laddr.lsap, llc->daddr.lsap);
        if (!llc_send_disc(sk))
                llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo);
+       sap = llc->sap;
+       /* Hold this for release_sock(), so that llc_backlog_rcv() could still
+        * use it.
+        */
+       llc_sap_hold(sap);
        if (!sock_flag(sk, SOCK_ZAPPED))
                llc_sap_remove_socket(llc->sap, sk);
        release_sock(sk);
+       llc_sap_put(sap);
        if (llc->dev)
                dev_put(llc->dev);
        sock_put(sk);
index 616cb9c..c31b068 100644 (file)
@@ -3008,6 +3008,7 @@ static int packet_release(struct socket *sock)
 
        packet_flush_mclist(sk);
 
+       lock_sock(sk);
        if (po->rx_ring.pg_vec) {
                memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 0);
@@ -3017,6 +3018,7 @@ static int packet_release(struct socket *sock)
                memset(&req_u, 0, sizeof(req_u));
                packet_set_ring(sk, &req_u, 1, 1);
        }
+       release_sock(sk);
 
        f = fanout_release(sk);
 
@@ -3643,6 +3645,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                union tpacket_req_u req_u;
                int len;
 
+               lock_sock(sk);
                switch (po->tp_version) {
                case TPACKET_V1:
                case TPACKET_V2:
@@ -3653,12 +3656,17 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                        len = sizeof(req_u.req3);
                        break;
                }
-               if (optlen < len)
-                       return -EINVAL;
-               if (copy_from_user(&req_u.req, optval, len))
-                       return -EFAULT;
-               return packet_set_ring(sk, &req_u, 0,
-                       optname == PACKET_TX_RING);
+               if (optlen < len) {
+                       ret = -EINVAL;
+               } else {
+                       if (copy_from_user(&req_u.req, optval, len))
+                               ret = -EFAULT;
+                       else
+                               ret = packet_set_ring(sk, &req_u, 0,
+                                                   optname == PACKET_TX_RING);
+               }
+               release_sock(sk);
+               return ret;
        }
        case PACKET_COPY_THRESH:
        {
@@ -4208,8 +4216,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        /* Added to avoid minimal code churn */
        struct tpacket_req *req = &req_u->req;
 
-       lock_sock(sk);
-
        rb = tx_ring ? &po->tx_ring : &po->rx_ring;
        rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
 
@@ -4347,7 +4353,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
        if (pg_vec)
                free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
-       release_sock(sk);
        return err;
 }
 
index b33e5ae..2aa07b5 100644 (file)
@@ -1135,3 +1135,4 @@ module_exit(qrtr_proto_fini);
 
 MODULE_DESCRIPTION("Qualcomm IPC-router driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_NETPROTO(PF_QIPCRTR);
index 31083b5..2e3f7b7 100644 (file)
@@ -556,46 +556,49 @@ static void sctp_v6_to_addr(union sctp_addr *addr, struct in6_addr *saddr,
        addr->v6.sin6_scope_id = 0;
 }
 
-/* Compare addresses exactly.
- * v4-mapped-v6 is also in consideration.
- */
-static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
-                           const union sctp_addr *addr2)
+static int __sctp_v6_cmp_addr(const union sctp_addr *addr1,
+                             const union sctp_addr *addr2)
 {
        if (addr1->sa.sa_family != addr2->sa.sa_family) {
                if (addr1->sa.sa_family == AF_INET &&
                    addr2->sa.sa_family == AF_INET6 &&
-                   ipv6_addr_v4mapped(&addr2->v6.sin6_addr)) {
-                       if (addr2->v6.sin6_port == addr1->v4.sin_port &&
-                           addr2->v6.sin6_addr.s6_addr32[3] ==
-                           addr1->v4.sin_addr.s_addr)
-                               return 1;
-               }
+                   ipv6_addr_v4mapped(&addr2->v6.sin6_addr) &&
+                   addr2->v6.sin6_addr.s6_addr32[3] ==
+                   addr1->v4.sin_addr.s_addr)
+                       return 1;
+
                if (addr2->sa.sa_family == AF_INET &&
                    addr1->sa.sa_family == AF_INET6 &&
-                   ipv6_addr_v4mapped(&addr1->v6.sin6_addr)) {
-                       if (addr1->v6.sin6_port == addr2->v4.sin_port &&
-                           addr1->v6.sin6_addr.s6_addr32[3] ==
-                           addr2->v4.sin_addr.s_addr)
-                               return 1;
-               }
+                   ipv6_addr_v4mapped(&addr1->v6.sin6_addr) &&
+                   addr1->v6.sin6_addr.s6_addr32[3] ==
+                   addr2->v4.sin_addr.s_addr)
+                       return 1;
+
                return 0;
        }
-       if (addr1->v6.sin6_port != addr2->v6.sin6_port)
-               return 0;
+
        if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
                return 0;
+
        /* If this is a linklocal address, compare the scope_id. */
-       if (ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) {
-               if (addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
-                   (addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)) {
-                       return 0;
-               }
-       }
+       if ((ipv6_addr_type(&addr1->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) &&
+           addr1->v6.sin6_scope_id && addr2->v6.sin6_scope_id &&
+           addr1->v6.sin6_scope_id != addr2->v6.sin6_scope_id)
+               return 0;
 
        return 1;
 }
 
+/* Compare addresses exactly.
+ * v4-mapped-v6 is also in consideration.
+ */
+static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
+                           const union sctp_addr *addr2)
+{
+       return __sctp_v6_cmp_addr(addr1, addr2) &&
+              addr1->v6.sin6_port == addr2->v6.sin6_port;
+}
+
 /* Initialize addr struct to INADDR_ANY. */
 static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
 {
@@ -875,8 +878,8 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
                               const union sctp_addr *addr2,
                               struct sctp_sock *opt)
 {
-       struct sctp_af *af1, *af2;
        struct sock *sk = sctp_opt2sk(opt);
+       struct sctp_af *af1, *af2;
 
        af1 = sctp_get_af_specific(addr1->sa.sa_family);
        af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -892,10 +895,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
        if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
                return 1;
 
-       if (addr1->sa.sa_family != addr2->sa.sa_family)
-               return 0;
-
-       return af1->cmp_addr(addr1, addr2);
+       return __sctp_v6_cmp_addr(addr1, addr2);
 }
 
 /* Verify that the provided sockaddr looks bindable.   Common verification,
index 5f8046c..f5d4b69 100644 (file)
@@ -1259,14 +1259,12 @@ static int smc_shutdown(struct socket *sock, int how)
                rc = smc_close_shutdown_write(smc);
                break;
        case SHUT_RD:
-               if (sk->sk_state == SMC_LISTEN)
-                       rc = smc_close_active(smc);
-               else
-                       rc = 0;
-                       /* nothing more to do because peer is not involved */
+               rc = 0;
+               /* nothing more to do because peer is not involved */
                break;
        }
-       rc1 = kernel_sock_shutdown(smc->clcsock, how);
+       if (smc->clcsock)
+               rc1 = kernel_sock_shutdown(smc->clcsock, how);
        /* map sock_shutdown_cmd constants to sk_shutdown value range */
        sk->sk_shutdown |= how + 1;
 
index b9283ce..805b139 100644 (file)
@@ -296,9 +296,9 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
                                        strp_start_timer(strp, timeo);
                                }
 
+                               stm->accum_len += cand_len;
                                strp->need_bytes = stm->strp.full_len -
                                                       stm->accum_len;
-                               stm->accum_len += cand_len;
                                stm->early_eaten = cand_len;
                                STRP_STATS_ADD(strp->stats.bytes, cand_len);
                                desc->count = 0; /* Stop reading socket */
@@ -321,6 +321,7 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
                /* Hurray, we have a new message! */
                cancel_delayed_work(&strp->msg_timer_work);
                strp->skb_head = NULL;
+               strp->need_bytes = 0;
                STRP_STATS_INCR(strp->stats.msgs);
 
                /* Give skb to upper layer */
@@ -410,9 +411,7 @@ void strp_data_ready(struct strparser *strp)
                return;
 
        if (strp->need_bytes) {
-               if (strp_peek_len(strp) >= strp->need_bytes)
-                       strp->need_bytes = 0;
-               else
+               if (strp_peek_len(strp) < strp->need_bytes)
                        return;
        }
 
index 0f08934..c81ef5e 100644 (file)
@@ -1375,6 +1375,7 @@ rpc_gssd_dummy_depopulate(struct dentry *pipe_dentry)
        struct dentry *clnt_dir = pipe_dentry->d_parent;
        struct dentry *gssd_dir = clnt_dir->d_parent;
 
+       dget(pipe_dentry);
        __rpc_rmpipe(d_inode(clnt_dir), pipe_dentry);
        __rpc_depopulate(clnt_dir, gssd_dummy_info_file, 0, 1);
        __rpc_depopulate(gssd_dir, gssd_dummy_clnt_dir, 0, 1);
index 32dc33a..5453e56 100644 (file)
@@ -777,7 +777,7 @@ int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg,
 
        ret = tipc_bearer_get_name(net, bearer_name, bearer_id);
        if (ret || !mon)
-               return -EINVAL;
+               return 0;
 
        hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
                          NLM_F_MULTI, TIPC_NL_MON_GET);
index b1fe209..dd1c4fa 100644 (file)
@@ -241,7 +241,8 @@ err:
 static struct publication *tipc_service_remove_publ(struct net *net,
                                                    struct tipc_service *sc,
                                                    u32 lower, u32 upper,
-                                                   u32 node, u32 key)
+                                                   u32 node, u32 key,
+                                                   struct service_range **rng)
 {
        struct tipc_subscription *sub, *tmp;
        struct service_range *sr;
@@ -275,19 +276,15 @@ static struct publication *tipc_service_remove_publ(struct net *net,
 
        list_del(&p->all_publ);
        list_del(&p->local_publ);
-
-       /* Remove service range item if this was its last publication */
-       if (list_empty(&sr->all_publ)) {
+       if (list_empty(&sr->all_publ))
                last = true;
-               rb_erase(&sr->tree_node, &sc->ranges);
-               kfree(sr);
-       }
 
        /* Notify any waiting subscriptions */
        list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) {
                tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN,
                                        p->port, p->node, p->scope, last);
        }
+       *rng = sr;
        return p;
 }
 
@@ -379,13 +376,20 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
                                             u32 node, u32 key)
 {
        struct tipc_service *sc = tipc_service_find(net, type);
+       struct service_range *sr = NULL;
        struct publication *p = NULL;
 
        if (!sc)
                return NULL;
 
        spin_lock_bh(&sc->lock);
-       p = tipc_service_remove_publ(net, sc, lower, upper, node, key);
+       p = tipc_service_remove_publ(net, sc, lower, upper, node, key, &sr);
+
+       /* Remove service range item if this was its last publication */
+       if (sr && list_empty(&sr->all_publ)) {
+               rb_erase(&sr->tree_node, &sc->ranges);
+               kfree(sr);
+       }
 
        /* Delete service item if this no more publications and subscriptions */
        if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) {
@@ -665,13 +669,14 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
 /**
  * tipc_nametbl_subscribe - add a subscription object to the name table
  */
-void tipc_nametbl_subscribe(struct tipc_subscription *sub)
+bool tipc_nametbl_subscribe(struct tipc_subscription *sub)
 {
        struct name_table *nt = tipc_name_table(sub->net);
        struct tipc_net *tn = tipc_net(sub->net);
        struct tipc_subscr *s = &sub->evt.s;
        u32 type = tipc_sub_read(s, seq.type);
        struct tipc_service *sc;
+       bool res = true;
 
        spin_lock_bh(&tn->nametbl_lock);
        sc = tipc_service_find(sub->net, type);
@@ -685,8 +690,10 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub)
                pr_warn("Failed to subscribe for {%u,%u,%u}\n", type,
                        tipc_sub_read(s, seq.lower),
                        tipc_sub_read(s, seq.upper));
+               res = false;
        }
        spin_unlock_bh(&tn->nametbl_lock);
+       return res;
 }
 
 /**
@@ -744,16 +751,17 @@ int tipc_nametbl_init(struct net *net)
 static void tipc_service_delete(struct net *net, struct tipc_service *sc)
 {
        struct service_range *sr, *tmpr;
-       struct publication *p, *tmpb;
+       struct publication *p, *tmp;
 
        spin_lock_bh(&sc->lock);
        rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) {
-               list_for_each_entry_safe(p, tmpb,
-                                        &sr->all_publ, all_publ) {
+               list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) {
                        tipc_service_remove_publ(net, sc, p->lower, p->upper,
-                                                p->node, p->key);
+                                                p->node, p->key, &sr);
                        kfree_rcu(p, rcu);
                }
+               rb_erase(&sr->tree_node, &sc->ranges);
+               kfree(sr);
        }
        hlist_del_init_rcu(&sc->service_list);
        spin_unlock_bh(&sc->lock);
index 4b14fc2..0febba4 100644 (file)
@@ -126,7 +126,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
 struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
                                             u32 lower, u32 upper,
                                             u32 node, u32 key);
-void tipc_nametbl_subscribe(struct tipc_subscription *s);
+bool tipc_nametbl_subscribe(struct tipc_subscription *s);
 void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
 int tipc_nametbl_init(struct net *net);
 void tipc_nametbl_stop(struct net *net);
index 856f9e9..4fbaa04 100644 (file)
@@ -252,6 +252,8 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
                u64 *w0 = (u64 *)&node_id[0];
                u64 *w1 = (u64 *)&node_id[8];
 
+               if (!attrs[TIPC_NLA_NET_NODEID_W1])
+                       return -EINVAL;
                *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]);
                *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
                tipc_net_init(net, node_id, 0);
index b76f13f..6ff2254 100644 (file)
@@ -79,7 +79,10 @@ const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
 
 const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
        [TIPC_NLA_NET_UNSPEC]           = { .type = NLA_UNSPEC },
-       [TIPC_NLA_NET_ID]               = { .type = NLA_U32 }
+       [TIPC_NLA_NET_ID]               = { .type = NLA_U32 },
+       [TIPC_NLA_NET_ADDR]             = { .type = NLA_U32 },
+       [TIPC_NLA_NET_NODEID]           = { .type = NLA_U64 },
+       [TIPC_NLA_NET_NODEID_W1]        = { .type = NLA_U64 },
 };
 
 const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
index c77dd2f..6f98b56 100644 (file)
@@ -2232,8 +2232,8 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
        struct net *net = sock_net(skb->sk);
        u32 prev_bearer = cb->args[0];
        struct tipc_nl_msg msg;
+       int bearer_id;
        int err;
-       int i;
 
        if (prev_bearer == MAX_BEARERS)
                return 0;
@@ -2243,16 +2243,13 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb)
        msg.seq = cb->nlh->nlmsg_seq;
 
        rtnl_lock();
-       for (i = prev_bearer; i < MAX_BEARERS; i++) {
-               prev_bearer = i;
+       for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) {
                err = __tipc_nl_add_monitor(net, &msg, prev_bearer);
                if (err)
-                       goto out;
+                       break;
        }
-
-out:
        rtnl_unlock();
-       cb->args[0] = prev_bearer;
+       cb->args[0] = bearer_id;
 
        return skb->len;
 }
index 1fd1c8b..252a52a 100644 (file)
@@ -1278,7 +1278,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
        struct tipc_msg *hdr = &tsk->phdr;
        struct tipc_name_seq *seq;
        struct sk_buff_head pkts;
-       u32 dnode, dport;
+       u32 dport, dnode = 0;
        u32 type, inst;
        int mtu, rc;
 
@@ -1348,6 +1348,8 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen)
                msg_set_destnode(hdr, dnode);
                msg_set_destport(hdr, dest->addr.id.ref);
                msg_set_hdr_sz(hdr, BASIC_H_SIZE);
+       } else {
+               return -EINVAL;
        }
 
        /* Block or return if destination link is congested */
index b7d80bc..f340e53 100644 (file)
@@ -153,7 +153,10 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net,
        memcpy(&sub->evt.s, s, sizeof(*s));
        spin_lock_init(&sub->lock);
        kref_init(&sub->kref);
-       tipc_nametbl_subscribe(sub);
+       if (!tipc_nametbl_subscribe(sub)) {
+               kfree(sub);
+               return NULL;
+       }
        timer_setup(&sub->timer, tipc_sub_timeout, 0);
        timeout = tipc_sub_read(&sub->evt.s, timeout);
        if (timeout != TIPC_WAIT_FOREVER)
index 4dc766b..71e7959 100644 (file)
@@ -41,6 +41,8 @@
 #include <net/strparser.h>
 #include <net/tls.h>
 
+#define MAX_IV_SIZE    TLS_CIPHER_AES_GCM_128_IV_SIZE
+
 static int tls_do_decryption(struct sock *sk,
                             struct scatterlist *sgin,
                             struct scatterlist *sgout,
@@ -673,7 +675,7 @@ static int decrypt_skb(struct sock *sk, struct sk_buff *skb,
 {
        struct tls_context *tls_ctx = tls_get_ctx(sk);
        struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
-       char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + tls_ctx->rx.iv_size];
+       char iv[TLS_CIPHER_AES_GCM_128_SALT_SIZE + MAX_IV_SIZE];
        struct scatterlist sgin_arr[MAX_SKB_FRAGS + 2];
        struct scatterlist *sgin = &sgin_arr[0];
        struct strp_msg *rxm = strp_msg(skb);
@@ -1094,6 +1096,12 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx)
                goto free_priv;
        }
 
+       /* Sanity-check the IV size for stack allocations. */
+       if (iv_size > MAX_IV_SIZE) {
+               rc = -EINVAL;
+               goto free_priv;
+       }
+
        cctx->prepend_size = TLS_HEADER_SIZE + nonce_size;
        cctx->tag_size = tag_size;
        cctx->overhead_size = cctx->prepend_size + cctx->tag_size;
index aac9b8f..c1076c1 100644 (file)
@@ -2018,7 +2018,13 @@ const struct vsock_transport *vsock_core_get_transport(void)
 }
 EXPORT_SYMBOL_GPL(vsock_core_get_transport);
 
+static void __exit vsock_exit(void)
+{
+       /* Do nothing.  This function makes this module removable. */
+}
+
 module_init(vsock_init_tables);
+module_exit(vsock_exit);
 
 MODULE_AUTHOR("VMware, Inc.");
 MODULE_DESCRIPTION("VMware Virtual Socket Family");
index 830c555..49b1355 100644 (file)
@@ -56,6 +56,21 @@ struct dummy {
        unsigned long jiffies_expire;
 };
 
+/*
+ * The constructor makes more sense together with klp_shadow_get_or_alloc().
+ * In this example, it would be safe to assign the pointer also to the shadow
+ * variable returned by klp_shadow_alloc().  But we wanted to show the more
+ * complicated use of the API.
+ */
+static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
+{
+       void **shadow_leak = shadow_data;
+       void *leak = ctor_data;
+
+       *shadow_leak = leak;
+       return 0;
+}
+
 struct dummy *livepatch_fix1_dummy_alloc(void)
 {
        struct dummy *d;
@@ -74,7 +89,8 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
         * pointer to handle resource release.
         */
        leak = kzalloc(sizeof(int), GFP_KERNEL);
-       klp_shadow_alloc(d, SV_LEAK, &leak, sizeof(leak), GFP_KERNEL);
+       klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
+                        shadow_leak_ctor, leak);
 
        pr_info("%s: dummy @ %p, expires @ %lx\n",
                __func__, d, d->jiffies_expire);
@@ -82,9 +98,19 @@ struct dummy *livepatch_fix1_dummy_alloc(void)
        return d;
 }
 
+static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
+{
+       void *d = obj;
+       void **shadow_leak = shadow_data;
+
+       kfree(*shadow_leak);
+       pr_info("%s: dummy @ %p, prevented leak @ %p\n",
+                        __func__, d, *shadow_leak);
+}
+
 void livepatch_fix1_dummy_free(struct dummy *d)
 {
-       void **shadow_leak, *leak;
+       void **shadow_leak;
 
        /*
         * Patch: fetch the saved SV_LEAK shadow variable, detach and
@@ -93,15 +119,10 @@ void livepatch_fix1_dummy_free(struct dummy *d)
         * was loaded.)
         */
        shadow_leak = klp_shadow_get(d, SV_LEAK);
-       if (shadow_leak) {
-               leak = *shadow_leak;
-               klp_shadow_free(d, SV_LEAK);
-               kfree(leak);
-               pr_info("%s: dummy @ %p, prevented leak @ %p\n",
-                        __func__, d, leak);
-       } else {
+       if (shadow_leak)
+               klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
+       else
                pr_info("%s: dummy @ %p leaked!\n", __func__, d);
-       }
 
        kfree(d);
 }
@@ -147,7 +168,7 @@ static int livepatch_shadow_fix1_init(void)
 static void livepatch_shadow_fix1_exit(void)
 {
        /* Cleanup any existing SV_LEAK shadow variables */
-       klp_shadow_free_all(SV_LEAK);
+       klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
 
        WARN_ON(klp_unregister_patch(&patch));
 }
index ff9948f..b34c7bf 100644 (file)
@@ -53,39 +53,42 @@ struct dummy {
 bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
 {
        int *shadow_count;
-       int count;
 
        /*
         * Patch: handle in-flight dummy structures, if they do not
         * already have a SV_COUNTER shadow variable, then attach a
         * new one.
         */
-       count = 0;
        shadow_count = klp_shadow_get_or_alloc(d, SV_COUNTER,
-                                              &count, sizeof(count),
-                                              GFP_NOWAIT);
+                               sizeof(*shadow_count), GFP_NOWAIT,
+                               NULL, NULL);
        if (shadow_count)
                *shadow_count += 1;
 
        return time_after(jiffies, d->jiffies_expire);
 }
 
+static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
+{
+       void *d = obj;
+       void **shadow_leak = shadow_data;
+
+       kfree(*shadow_leak);
+       pr_info("%s: dummy @ %p, prevented leak @ %p\n",
+                        __func__, d, *shadow_leak);
+}
+
 void livepatch_fix2_dummy_free(struct dummy *d)
 {
-       void **shadow_leak, *leak;
+       void **shadow_leak;
        int *shadow_count;
 
        /* Patch: copy the memory leak patch from the fix1 module. */
        shadow_leak = klp_shadow_get(d, SV_LEAK);
-       if (shadow_leak) {
-               leak = *shadow_leak;
-               klp_shadow_free(d, SV_LEAK);
-               kfree(leak);
-               pr_info("%s: dummy @ %p, prevented leak @ %p\n",
-                        __func__, d, leak);
-       } else {
+       if (shadow_leak)
+               klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor);
+       else
                pr_info("%s: dummy @ %p leaked!\n", __func__, d);
-       }
 
        /*
         * Patch: fetch the SV_COUNTER shadow variable and display
@@ -95,7 +98,7 @@ void livepatch_fix2_dummy_free(struct dummy *d)
        if (shadow_count) {
                pr_info("%s: dummy @ %p, check counter = %d\n",
                        __func__, d, *shadow_count);
-               klp_shadow_free(d, SV_COUNTER);
+               klp_shadow_free(d, SV_COUNTER, NULL);
        }
 
        kfree(d);
@@ -142,7 +145,7 @@ static int livepatch_shadow_fix2_init(void)
 static void livepatch_shadow_fix2_exit(void)
 {
        /* Cleanup any existing SV_COUNTER shadow variables */
-       klp_shadow_free_all(SV_COUNTER);
+       klp_shadow_free_all(SV_COUNTER, NULL);
 
        WARN_ON(klp_unregister_patch(&patch));
 }
index f69764d..e30e30b 100644 (file)
@@ -36,8 +36,6 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
        struct snd_rawmidi_params params;
        unsigned int val;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(params.stream, &src->stream) ||
            get_user(params.buffer_size, &src->buffer_size) ||
            get_user(params.avail_min, &src->avail_min) ||
@@ -46,8 +44,12 @@ static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
        params.no_active_sensing = val;
        switch (params.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                return snd_rawmidi_output_params(rfile->output, &params);
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                return snd_rawmidi_input_params(rfile->input, &params);
        }
        return -EINVAL;
@@ -67,16 +69,18 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
@@ -112,16 +116,18 @@ static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
        int err;
        struct snd_rawmidi_status status;
 
-       if (rfile->output == NULL)
-               return -EINVAL;
        if (get_user(status.stream, &src->stream))
                return -EFAULT;
 
        switch (status.stream) {
        case SNDRV_RAWMIDI_STREAM_OUTPUT:
+               if (!rfile->output)
+                       return -EINVAL;
                err = snd_rawmidi_output_status(rfile->output, &status);
                break;
        case SNDRV_RAWMIDI_STREAM_INPUT:
+               if (!rfile->input)
+                       return -EINVAL;
                err = snd_rawmidi_input_status(rfile->input, &status);
                break;
        default:
index 7a111a1..b0c8c79 100644 (file)
@@ -1647,7 +1647,8 @@ static void azx_check_snoop_available(struct azx *chip)
                 */
                u8 val;
                pci_read_config_byte(chip->pci, 0x42, &val);
-               if (!(val & 0x80) && chip->pci->revision == 0x30)
+               if (!(val & 0x80) && (chip->pci->revision == 0x30 ||
+                                     chip->pci->revision == 0x20))
                        snoop = false;
        }
 
index aef1f52..fc77bf7 100644 (file)
@@ -6370,6 +6370,8 @@ static const struct hda_fixup alc269_fixups[] = {
                        { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
                        { }
                },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MIC
        },
 };
 
@@ -6573,6 +6575,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+       SND_PCI_QUIRK(0x17aa, 0x3138, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x3112, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
index 6d7cde5..e2cf55c 100644 (file)
@@ -125,7 +125,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
        }
 
        usb_fill_int_urb(urb, line6->usbdev,
-                        usb_sndbulkpipe(line6->usbdev,
+                        usb_sndintpipe(line6->usbdev,
                                         line6->properties->ep_ctrl_w),
                         transfer_buffer, length, midi_sent, line6,
                         line6->interval);
index 6edd177..2ba95d6 100644 (file)
@@ -135,6 +135,15 @@ struct kvm_arch_memory_slot {
 #define KVM_REG_ARM_CRM_SHIFT          7
 #define KVM_REG_ARM_32_CRN_MASK                0x0000000000007800
 #define KVM_REG_ARM_32_CRN_SHIFT       11
+/*
+ * For KVM currently all guest registers are nonsecure, but we reserve a bit
+ * in the encoding to distinguish secure from nonsecure for AArch32 system
+ * registers that are banked by security. This is 1 for the secure banked
+ * register, and 0 for the nonsecure banked register or if the register is
+ * not banked by security.
+ */
+#define KVM_REG_ARM_SECURE_MASK        0x0000000010000000
+#define KVM_REG_ARM_SECURE_SHIFT       28
 
 #define ARM_CP15_REG_SHIFT_MASK(x,n) \
        (((x) << KVM_REG_ARM_ ## n ## _SHIFT) & KVM_REG_ARM_ ## n ## _MASK)
index fb3a6de..6847d85 100644 (file)
 # define NEED_MOVBE    0
 #endif
 
-#ifdef CONFIG_X86_5LEVEL
-# define NEED_LA57     (1<<(X86_FEATURE_LA57 & 31))
-#else
-# define NEED_LA57     0
-#endif
-
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_PARAVIRT
 /* Paravirtualized systems may not have PSE or PGE available */
 #define REQUIRED_MASK13        0
 #define REQUIRED_MASK14        0
 #define REQUIRED_MASK15        0
-#define REQUIRED_MASK16        (NEED_LA57)
+#define REQUIRED_MASK16        0
 #define REQUIRED_MASK17        0
 #define REQUIRED_MASK18        0
 #define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
index f3a9604..c535c2f 100644 (file)
@@ -354,8 +354,25 @@ struct kvm_xcrs {
        __u64 padding[16];
 };
 
-/* definition of registers in kvm_run */
+#define KVM_SYNC_X86_REGS      (1UL << 0)
+#define KVM_SYNC_X86_SREGS     (1UL << 1)
+#define KVM_SYNC_X86_EVENTS    (1UL << 2)
+
+#define KVM_SYNC_X86_VALID_FIELDS \
+       (KVM_SYNC_X86_REGS| \
+        KVM_SYNC_X86_SREGS| \
+        KVM_SYNC_X86_EVENTS)
+
+/* kvm_sync_regs struct included by kvm_run struct */
 struct kvm_sync_regs {
+       /* Members of this structure are potentially malicious.
+        * Care must be taken by code reading, esp. interpreting,
+        * data fields from them inside KVM to prevent TOCTOU and
+        * double-fetch types of vulnerabilities.
+        */
+       struct kvm_regs regs;
+       struct kvm_sregs sregs;
+       struct kvm_vcpu_events events;
 };
 
 #define KVM_X86_QUIRK_LINT0_REENABLED  (1 << 0)
index 04e32f9..1827c2f 100644 (file)
@@ -151,11 +151,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
  * required ordering.
  */
 
-#define READ_ONCE(x) \
-       ({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
-
-#define WRITE_ONCE(x, val) \
-       ({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
+#define READ_ONCE(x)                                   \
+({                                                     \
+       union { typeof(x) __val; char __c[1]; } __u =   \
+               { .__c = { 0 } };                       \
+       __read_once_size(&(x), __u.__c, sizeof(x));     \
+       __u.__val;                                      \
+})
+
+#define WRITE_ONCE(x, val)                             \
+({                                                     \
+       union { typeof(x) __val; char __c[1]; } __u =   \
+               { .__val = (val) };                     \
+       __write_once_size(&(x), __u.__c, sizeof(x));    \
+       __u.__val;                                      \
+})
 
 
 #ifndef __fallthrough
index edfeaba..a1a959b 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef _LINUX_CORESIGHT_PMU_H
index f8b134f..e7ee328 100644 (file)
@@ -27,6 +27,9 @@
 # define MAP_UNINITIALIZED 0x0         /* Don't support this flag */
 #endif
 
+/* 0x0100 - 0x80000 flags are defined in asm-generic/mman.h */
+#define MAP_FIXED_NOREPLACE    0x100000        /* MAP_FIXED which doesn't unmap underlying mapping */
+
 /*
  * Flags for mlock
  */
index 9d07465..c5ec897 100644 (file)
@@ -864,6 +864,7 @@ enum bpf_func_id {
 /* BPF_FUNC_skb_set_tunnel_key flags. */
 #define BPF_F_ZERO_CSUM_TX             (1ULL << 1)
 #define BPF_F_DONT_FRAGMENT            (1ULL << 2)
+#define BPF_F_SEQ_NUMBER               (1ULL << 3)
 
 /* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
  * BPF_FUNC_perf_event_read_value flags.
index 6d94477..68699f6 100644 (file)
@@ -941,4 +941,43 @@ enum {
        IFLA_EVENT_BONDING_OPTIONS,     /* change in bonding options */
 };
 
+/* tun section */
+
+enum {
+       IFLA_TUN_UNSPEC,
+       IFLA_TUN_OWNER,
+       IFLA_TUN_GROUP,
+       IFLA_TUN_TYPE,
+       IFLA_TUN_PI,
+       IFLA_TUN_VNET_HDR,
+       IFLA_TUN_PERSIST,
+       IFLA_TUN_MULTI_QUEUE,
+       IFLA_TUN_NUM_QUEUES,
+       IFLA_TUN_NUM_DISABLED_QUEUES,
+       __IFLA_TUN_MAX,
+};
+
+#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
+
+/* rmnet section */
+
+#define RMNET_FLAGS_INGRESS_DEAGGREGATION         (1U << 0)
+#define RMNET_FLAGS_INGRESS_MAP_COMMANDS          (1U << 1)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4           (1U << 2)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4            (1U << 3)
+
+enum {
+       IFLA_RMNET_UNSPEC,
+       IFLA_RMNET_MUX_ID,
+       IFLA_RMNET_FLAGS,
+       __IFLA_RMNET_MAX,
+};
+
+#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1)
+
+struct ifla_rmnet_flags {
+       __u32   flags;
+       __u32   mask;
+};
+
 #endif /* _UAPI_LINUX_IF_LINK_H */
index 6b89f87..1065006 100644 (file)
@@ -396,6 +396,10 @@ struct kvm_run {
                char padding[256];
        };
 
+       /* 2048 is the size of the char array used to bound/pad the size
+        * of the union that holds sync regs.
+        */
+       #define SYNC_REGS_SIZE_BYTES 2048
        /*
         * shared registers between kvm and userspace.
         * kvm_valid_regs specifies the register classes set by the host
@@ -407,7 +411,7 @@ struct kvm_run {
        __u64 kvm_dirty_regs;
        union {
                struct kvm_sync_regs regs;
-               char padding[2048];
+               char padding[SYNC_REGS_SIZE_BYTES];
        } s;
 };
 
@@ -936,6 +940,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
 #define KVM_CAP_GET_MSR_FEATURES 153
+#define KVM_CAP_HYPERV_EVENTFD 154
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1375,6 +1380,10 @@ struct kvm_enc_region {
 #define KVM_MEMORY_ENCRYPT_REG_REGION    _IOR(KVMIO, 0xbb, struct kvm_enc_region)
 #define KVM_MEMORY_ENCRYPT_UNREG_REGION  _IOR(KVMIO, 0xbc, struct kvm_enc_region)
 
+/* Available with KVM_CAP_HYPERV_EVENTFD */
+#define KVM_HYPERV_EVENTFD        _IOW(KVMIO,  0xbd, struct kvm_hyperv_eventfd)
+
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
        /* Guest initialization commands */
@@ -1515,4 +1524,14 @@ struct kvm_assigned_msix_entry {
 #define KVM_ARM_DEV_EL1_PTIMER         (1 << 1)
 #define KVM_ARM_DEV_PMU                        (1 << 2)
 
+struct kvm_hyperv_eventfd {
+       __u32 conn_id;
+       __s32 fd;
+       __u32 flags;
+       __u32 padding[3];
+};
+
+#define KVM_HYPERV_CONN_ID_MASK                0x00ffffff
+#define KVM_HYPERV_EVENTFD_DEASSIGN    (1 << 0)
+
 #endif /* __LINUX_KVM_H */
index 912b85b..b8e288a 100644 (file)
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {
 #define PERF_RECORD_MISC_COMM_EXEC             (1 << 13)
 #define PERF_RECORD_MISC_SWITCH_OUT            (1 << 13)
 /*
- * Indicates that the content of PERF_SAMPLE_IP points to
- * the actual instruction that triggered the event. See also
- * perf_event_attr::precise_ip.
+ * These PERF_RECORD_MISC_* flags below are safely reused
+ * for the following events:
+ *
+ *   PERF_RECORD_MISC_EXACT_IP           - PERF_RECORD_SAMPLE of precise events
+ *   PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events
+ *
+ *
+ * PERF_RECORD_MISC_EXACT_IP:
+ *   Indicates that the content of PERF_SAMPLE_IP points to
+ *   the actual instruction that triggered the event. See also
+ *   perf_event_attr::precise_ip.
+ *
+ * PERF_RECORD_MISC_SWITCH_OUT_PREEMPT:
+ *   Indicates that thread was preempted in TASK_RUNNING state.
  */
 #define PERF_RECORD_MISC_EXACT_IP              (1 << 14)
+#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT    (1 << 14)
 /*
  * Reserve the last bit to indicate some extended misc field
  */
index 07d6158..ed0a120 100644 (file)
@@ -242,6 +242,7 @@ typedef int __bitwise snd_pcm_format_t;
 #define        SNDRV_PCM_FORMAT_DSD_U16_BE     ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */
 #define        SNDRV_PCM_FORMAT_DSD_U32_BE     ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */
 #define        SNDRV_PCM_FORMAT_LAST           SNDRV_PCM_FORMAT_DSD_U32_BE
+#define        SNDRV_PCM_FORMAT_FIRST          SNDRV_PCM_FORMAT_S8
 
 #ifdef SNDRV_LITTLE_ENDIAN
 #define        SNDRV_PCM_FORMAT_S16            SNDRV_PCM_FORMAT_S16_LE
index f6a1bab..cb7154e 100644 (file)
@@ -433,7 +433,7 @@ match:
 
        if (ambiguous_option) {
                 fprintf(stderr,
-                        " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
+                        " Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n",
                         arg,
                         (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
                         ambiguous_option->long_name,
@@ -458,7 +458,7 @@ static void check_typos(const char *arg, const struct option *options)
                return;
 
        if (strstarts(arg, "no-")) {
-               fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
+               fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
                exit(129);
        }
 
@@ -466,7 +466,7 @@ static void check_typos(const char *arg, const struct option *options)
                if (!options->long_name)
                        continue;
                if (strstarts(options->long_name, arg)) {
-                       fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
+                       fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
                        exit(129);
                }
        }
index 8ae824d..f76d991 100644 (file)
@@ -31,8 +31,8 @@ INCLUDES := -I$(srctree)/tools/include \
            -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
            -I$(srctree)/tools/objtool/arch/$(ARCH)/include
 WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
-CFLAGS   += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
-LDFLAGS  += -lelf $(LIBSUBCMD)
+CFLAGS   += -Werror $(WARNINGS) $(HOSTCFLAGS) -g $(INCLUDES)
+LDFLAGS  += -lelf $(LIBSUBCMD) $(HOSTLDFLAGS)
 
 # Allow old libelf to be used:
 elfshdr := $(shell echo '$(pound)include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
index 5b4fff3..32f4a89 100644 (file)
@@ -334,6 +334,11 @@ annotate.*::
 
                99.93 â”‚      mov    %eax,%eax
 
+       annotate.offset_level::
+               Default is '1', meaning just jump targets will have offsets show right beside
+               the instruction. When set to '2' 'call' instructions will also have its offsets
+               shown, 3 or higher will show offsets for all instructions.
+
 hist.*::
        hist.percentage::
                This option control the way to calculate overhead of filtered entries -
index b021141..8806ed5 100644 (file)
@@ -67,6 +67,9 @@ OPTIONS
 --phys-data::
        Record/Report sample physical addresses
 
+In addition, for report all perf report options are valid, and for record
+all perf record options.
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-report[1]
index bb33601..63f938b 100644 (file)
@@ -104,8 +104,8 @@ OPTIONS for 'perf sched timehist'
     kallsyms pathname
 
 -g::
---no-call-graph::
-       Do not display call chains if present.
+--call-graph::
+       Display call chains if present (default on).
 
 --max-stack::
        Maximum number of functions to display in backtrace, default 5.
index 36ec025..afdafe2 100644 (file)
@@ -228,14 +228,15 @@ OPTIONS
        For sample events it's possible to display misc field with -F +misc option,
        following letters are displayed for each bit:
 
-         PERF_RECORD_MISC_KERNEL        K
-         PERF_RECORD_MISC_USER          U
-         PERF_RECORD_MISC_HYPERVISOR    H
-         PERF_RECORD_MISC_GUEST_KERNEL  G
-         PERF_RECORD_MISC_GUEST_USER    g
-         PERF_RECORD_MISC_MMAP_DATA*    M
-         PERF_RECORD_MISC_COMM_EXEC     E
-         PERF_RECORD_MISC_SWITCH_OUT    S
+         PERF_RECORD_MISC_KERNEL               K
+         PERF_RECORD_MISC_USER                 U
+         PERF_RECORD_MISC_HYPERVISOR           H
+         PERF_RECORD_MISC_GUEST_KERNEL         G
+         PERF_RECORD_MISC_GUEST_USER           g
+         PERF_RECORD_MISC_MMAP_DATA*           M
+         PERF_RECORD_MISC_COMM_EXEC            E
+         PERF_RECORD_MISC_SWITCH_OUT           S
+         PERF_RECORD_MISC_SWITCH_OUT_PREEMPT   Sp
 
          $ perf script -F +misc ...
           sched-messaging  1414 K     28690.636582:       4590 cycles ...
index f15b306..e6c3b4e 100644 (file)
@@ -153,7 +153,7 @@ perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- m
 
 -I msecs::
 --interval-print msecs::
-Print count deltas every N milliseconds (minimum: 10ms)
+Print count deltas every N milliseconds (minimum: 1ms)
 The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals.  Use with caution.
        example: 'perf stat -I 1000 -e cycles -a sleep 5'
 
index c7abd83..ae7dc46 100644 (file)
@@ -68,7 +68,7 @@ ifeq ($(NO_PERF_REGS),0)
 endif
 
 ifneq ($(NO_SYSCALL_TABLE),1)
-  CFLAGS += -DHAVE_SYSCALL_TABLE
+  CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
 endif
 
 # So far there's only x86 and arm libdw unwind support merged in perf.
@@ -847,7 +847,7 @@ ifndef NO_JVMTI
   ifeq ($(feature-jvmti), 1)
     $(call detected_var,JDIR)
   else
-    $(warning No openjdk development package found, please install JDK package)
+    $(warning No openjdk development package found, please install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel)
     NO_JVMTI := 1
   endif
 endif
diff --git a/tools/perf/arch/arm/include/arch-tests.h b/tools/perf/arch/arm/include/arch-tests.h
new file mode 100644 (file)
index 0000000..90ec4c8
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_TESTS_H
+#define ARCH_TESTS_H
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+struct thread;
+struct perf_sample;
+#endif
+
+extern struct test arch_tests[];
+
+#endif
index b30eff9..883c57f 100644 (file)
@@ -1,2 +1,4 @@
 libperf-y += regs_load.o
 libperf-y += dwarf-unwind.o
+
+libperf-y += arch-tests.o
diff --git a/tools/perf/arch/arm/tests/arch-tests.c b/tools/perf/arch/arm/tests/arch-tests.c
new file mode 100644 (file)
index 0000000..5b1543c
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <string.h>
+#include "tests/tests.h"
+#include "arch-tests.h"
+
+struct test arch_tests[] = {
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+       {
+               .desc = "DWARF unwind",
+               .func = test__dwarf_unwind,
+       },
+#endif
+       {
+               .func = NULL,
+       },
+};
index fa639e3..1ce6bdb 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <stdbool.h>
index 5c655ad..2f595cd 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <api/fs/fs.h>
index 5256741..1a12e64 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef INCLUDE__PERF_CS_ETM_H__
index ac4dffc..e047571 100644 (file)
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <string.h>
index d74eaa7..1a38e78 100644 (file)
@@ -21,7 +21,7 @@ _dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
 $(header): $(sys)/syscall_64.tbl $(systbl)
        @(test -d ../../kernel -a -d ../../tools -a -d ../perf && ( \
         (diff -B arch/x86/entry/syscalls/syscall_64.tbl ../../arch/x86/entry/syscalls/syscall_64.tbl >/dev/null) \
-        || echo "Warning: Kernel ABI header at 'tools/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
+        || echo "Warning: Kernel ABI header at 'tools/perf/arch/x86/entry/syscalls/syscall_64.tbl' differs from latest version at 'arch/x86/entry/syscalls/syscall_64.tbl'" >&2 )) || true
        $(Q)$(SHELL) '$(systbl)' $(sys)/syscall_64.tbl 'x86_64' > $@
 
 clean::
index 5bd1ba8..44f5aba 100644 (file)
@@ -1,21 +1,43 @@
 // SPDX-License-Identifier: GPL-2.0
 static struct ins x86__instructions[] = {
+       { .name = "adc",        .ops = &mov_ops,  },
+       { .name = "adcb",       .ops = &mov_ops,  },
+       { .name = "adcl",       .ops = &mov_ops,  },
        { .name = "add",        .ops = &mov_ops,  },
        { .name = "addl",       .ops = &mov_ops,  },
        { .name = "addq",       .ops = &mov_ops,  },
+       { .name = "addsd",      .ops = &mov_ops,  },
        { .name = "addw",       .ops = &mov_ops,  },
        { .name = "and",        .ops = &mov_ops,  },
+       { .name = "andb",       .ops = &mov_ops,  },
+       { .name = "andl",       .ops = &mov_ops,  },
+       { .name = "andpd",      .ops = &mov_ops,  },
+       { .name = "andps",      .ops = &mov_ops,  },
+       { .name = "andq",       .ops = &mov_ops,  },
+       { .name = "andw",       .ops = &mov_ops,  },
+       { .name = "bsr",        .ops = &mov_ops,  },
+       { .name = "bt",         .ops = &mov_ops,  },
+       { .name = "btr",        .ops = &mov_ops,  },
        { .name = "bts",        .ops = &mov_ops,  },
+       { .name = "btsq",       .ops = &mov_ops,  },
        { .name = "call",       .ops = &call_ops, },
        { .name = "callq",      .ops = &call_ops, },
+       { .name = "cmovbe",     .ops = &mov_ops,  },
+       { .name = "cmove",      .ops = &mov_ops,  },
+       { .name = "cmovae",     .ops = &mov_ops,  },
        { .name = "cmp",        .ops = &mov_ops,  },
        { .name = "cmpb",       .ops = &mov_ops,  },
        { .name = "cmpl",       .ops = &mov_ops,  },
        { .name = "cmpq",       .ops = &mov_ops,  },
        { .name = "cmpw",       .ops = &mov_ops,  },
        { .name = "cmpxch",     .ops = &mov_ops,  },
+       { .name = "cmpxchg",    .ops = &mov_ops,  },
+       { .name = "cs",         .ops = &mov_ops,  },
        { .name = "dec",        .ops = &dec_ops,  },
        { .name = "decl",       .ops = &dec_ops,  },
+       { .name = "divsd",      .ops = &mov_ops,  },
+       { .name = "divss",      .ops = &mov_ops,  },
+       { .name = "gs",         .ops = &mov_ops,  },
        { .name = "imul",       .ops = &mov_ops,  },
        { .name = "inc",        .ops = &dec_ops,  },
        { .name = "incl",       .ops = &dec_ops,  },
@@ -57,25 +79,68 @@ static struct ins x86__instructions[] = {
        { .name = "lea",        .ops = &mov_ops,  },
        { .name = "lock",       .ops = &lock_ops, },
        { .name = "mov",        .ops = &mov_ops,  },
+       { .name = "movapd",     .ops = &mov_ops,  },
+       { .name = "movaps",     .ops = &mov_ops,  },
        { .name = "movb",       .ops = &mov_ops,  },
        { .name = "movdqa",     .ops = &mov_ops,  },
+       { .name = "movdqu",     .ops = &mov_ops,  },
        { .name = "movl",       .ops = &mov_ops,  },
        { .name = "movq",       .ops = &mov_ops,  },
+       { .name = "movsd",      .ops = &mov_ops,  },
        { .name = "movslq",     .ops = &mov_ops,  },
+       { .name = "movss",      .ops = &mov_ops,  },
+       { .name = "movupd",     .ops = &mov_ops,  },
+       { .name = "movups",     .ops = &mov_ops,  },
+       { .name = "movw",       .ops = &mov_ops,  },
        { .name = "movzbl",     .ops = &mov_ops,  },
        { .name = "movzwl",     .ops = &mov_ops,  },
+       { .name = "mulsd",      .ops = &mov_ops,  },
+       { .name = "mulss",      .ops = &mov_ops,  },
        { .name = "nop",        .ops = &nop_ops,  },
        { .name = "nopl",       .ops = &nop_ops,  },
        { .name = "nopw",       .ops = &nop_ops,  },
        { .name = "or",         .ops = &mov_ops,  },
+       { .name = "orb",        .ops = &mov_ops,  },
        { .name = "orl",        .ops = &mov_ops,  },
+       { .name = "orps",       .ops = &mov_ops,  },
+       { .name = "orq",        .ops = &mov_ops,  },
+       { .name = "pand",       .ops = &mov_ops,  },
+       { .name = "paddq",      .ops = &mov_ops,  },
+       { .name = "pcmpeqb",    .ops = &mov_ops,  },
+       { .name = "por",        .ops = &mov_ops,  },
+       { .name = "rclb",       .ops = &mov_ops,  },
+       { .name = "rcll",       .ops = &mov_ops,  },
+       { .name = "retq",       .ops = &ret_ops,  },
+       { .name = "sbb",        .ops = &mov_ops,  },
+       { .name = "sbbl",       .ops = &mov_ops,  },
+       { .name = "sete",       .ops = &mov_ops,  },
+       { .name = "sub",        .ops = &mov_ops,  },
+       { .name = "subl",       .ops = &mov_ops,  },
+       { .name = "subq",       .ops = &mov_ops,  },
+       { .name = "subsd",      .ops = &mov_ops,  },
+       { .name = "subw",       .ops = &mov_ops,  },
        { .name = "test",       .ops = &mov_ops,  },
        { .name = "testb",      .ops = &mov_ops,  },
        { .name = "testl",      .ops = &mov_ops,  },
+       { .name = "ucomisd",    .ops = &mov_ops,  },
+       { .name = "ucomiss",    .ops = &mov_ops,  },
+       { .name = "vaddsd",     .ops = &mov_ops,  },
+       { .name = "vandpd",     .ops = &mov_ops,  },
+       { .name = "vmovdqa",    .ops = &mov_ops,  },
+       { .name = "vmovq",      .ops = &mov_ops,  },
+       { .name = "vmovsd",     .ops = &mov_ops,  },
+       { .name = "vmulsd",     .ops = &mov_ops,  },
+       { .name = "vorpd",      .ops = &mov_ops,  },
+       { .name = "vsubsd",     .ops = &mov_ops,  },
+       { .name = "vucomisd",   .ops = &mov_ops,  },
        { .name = "xadd",       .ops = &mov_ops,  },
        { .name = "xbeginl",    .ops = &jump_ops, },
        { .name = "xbeginq",    .ops = &jump_ops, },
-       { .name = "retq",       .ops = &ret_ops,  },
+       { .name = "xchg",       .ops = &mov_ops,  },
+       { .name = "xor",        .ops = &mov_ops, },
+       { .name = "xorb",       .ops = &mov_ops, },
+       { .name = "xorpd",      .ops = &mov_ops, },
+       { .name = "xorps",      .ops = &mov_ops, },
 };
 
 static bool x86__ins_is_fused(struct arch *arch, const char *ins1,
index 5aef183..4dfe426 100644 (file)
 # The format is:
 # <number> <abi> <name> <entry point>
 #
+# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
+#
 # The abi is "common", "64" or "x32" for this file.
 #
-0      common  read                    sys_read
-1      common  write                   sys_write
-2      common  open                    sys_open
-3      common  close                   sys_close
-4      common  stat                    sys_newstat
-5      common  fstat                   sys_newfstat
-6      common  lstat                   sys_newlstat
-7      common  poll                    sys_poll
-8      common  lseek                   sys_lseek
-9      common  mmap                    sys_mmap
-10     common  mprotect                sys_mprotect
-11     common  munmap                  sys_munmap
-12     common  brk                     sys_brk
-13     64      rt_sigaction            sys_rt_sigaction
-14     common  rt_sigprocmask          sys_rt_sigprocmask
-15     64      rt_sigreturn            sys_rt_sigreturn/ptregs
-16     64      ioctl                   sys_ioctl
-17     common  pread64                 sys_pread64
-18     common  pwrite64                sys_pwrite64
-19     64      readv                   sys_readv
-20     64      writev                  sys_writev
-21     common  access                  sys_access
-22     common  pipe                    sys_pipe
-23     common  select                  sys_select
-24     common  sched_yield             sys_sched_yield
-25     common  mremap                  sys_mremap
-26     common  msync                   sys_msync
-27     common  mincore                 sys_mincore
-28     common  madvise                 sys_madvise
-29     common  shmget                  sys_shmget
-30     common  shmat                   sys_shmat
-31     common  shmctl                  sys_shmctl
-32     common  dup                     sys_dup
-33     common  dup2                    sys_dup2
-34     common  pause                   sys_pause
-35     common  nanosleep               sys_nanosleep
-36     common  getitimer               sys_getitimer
-37     common  alarm                   sys_alarm
-38     common  setitimer               sys_setitimer
-39     common  getpid                  sys_getpid
-40     common  sendfile                sys_sendfile64
-41     common  socket                  sys_socket
-42     common  connect                 sys_connect
-43     common  accept                  sys_accept
-44     common  sendto                  sys_sendto
-45     64      recvfrom                sys_recvfrom
-46     64      sendmsg                 sys_sendmsg
-47     64      recvmsg                 sys_recvmsg
-48     common  shutdown                sys_shutdown
-49     common  bind                    sys_bind
-50     common  listen                  sys_listen
-51     common  getsockname             sys_getsockname
-52     common  getpeername             sys_getpeername
-53     common  socketpair              sys_socketpair
-54     64      setsockopt              sys_setsockopt
-55     64      getsockopt              sys_getsockopt
-56     common  clone                   sys_clone/ptregs
-57     common  fork                    sys_fork/ptregs
-58     common  vfork                   sys_vfork/ptregs
-59     64      execve                  sys_execve/ptregs
-60     common  exit                    sys_exit
-61     common  wait4                   sys_wait4
-62     common  kill                    sys_kill
-63     common  uname                   sys_newuname
-64     common  semget                  sys_semget
-65     common  semop                   sys_semop
-66     common  semctl                  sys_semctl
-67     common  shmdt                   sys_shmdt
-68     common  msgget                  sys_msgget
-69     common  msgsnd                  sys_msgsnd
-70     common  msgrcv                  sys_msgrcv
-71     common  msgctl                  sys_msgctl
-72     common  fcntl                   sys_fcntl
-73     common  flock                   sys_flock
-74     common  fsync                   sys_fsync
-75     common  fdatasync               sys_fdatasync
-76     common  truncate                sys_truncate
-77     common  ftruncate               sys_ftruncate
-78     common  getdents                sys_getdents
-79     common  getcwd                  sys_getcwd
-80     common  chdir                   sys_chdir
-81     common  fchdir                  sys_fchdir
-82     common  rename                  sys_rename
-83     common  mkdir                   sys_mkdir
-84     common  rmdir                   sys_rmdir
-85     common  creat                   sys_creat
-86     common  link                    sys_link
-87     common  unlink                  sys_unlink
-88     common  symlink                 sys_symlink
-89     common  readlink                sys_readlink
-90     common  chmod                   sys_chmod
-91     common  fchmod                  sys_fchmod
-92     common  chown                   sys_chown
-93     common  fchown                  sys_fchown
-94     common  lchown                  sys_lchown
-95     common  umask                   sys_umask
-96     common  gettimeofday            sys_gettimeofday
-97     common  getrlimit               sys_getrlimit
-98     common  getrusage               sys_getrusage
-99     common  sysinfo                 sys_sysinfo
-100    common  times                   sys_times
-101    64      ptrace                  sys_ptrace
-102    common  getuid                  sys_getuid
-103    common  syslog                  sys_syslog
-104    common  getgid                  sys_getgid
-105    common  setuid                  sys_setuid
-106    common  setgid                  sys_setgid
-107    common  geteuid                 sys_geteuid
-108    common  getegid                 sys_getegid
-109    common  setpgid                 sys_setpgid
-110    common  getppid                 sys_getppid
-111    common  getpgrp                 sys_getpgrp
-112    common  setsid                  sys_setsid
-113    common  setreuid                sys_setreuid
-114    common  setregid                sys_setregid
-115    common  getgroups               sys_getgroups
-116    common  setgroups               sys_setgroups
-117    common  setresuid               sys_setresuid
-118    common  getresuid               sys_getresuid
-119    common  setresgid               sys_setresgid
-120    common  getresgid               sys_getresgid
-121    common  getpgid                 sys_getpgid
-122    common  setfsuid                sys_setfsuid
-123    common  setfsgid                sys_setfsgid
-124    common  getsid                  sys_getsid
-125    common  capget                  sys_capget
-126    common  capset                  sys_capset
-127    64      rt_sigpending           sys_rt_sigpending
-128    64      rt_sigtimedwait         sys_rt_sigtimedwait
-129    64      rt_sigqueueinfo         sys_rt_sigqueueinfo
-130    common  rt_sigsuspend           sys_rt_sigsuspend
-131    64      sigaltstack             sys_sigaltstack
-132    common  utime                   sys_utime
-133    common  mknod                   sys_mknod
+0      common  read                    __x64_sys_read
+1      common  write                   __x64_sys_write
+2      common  open                    __x64_sys_open
+3      common  close                   __x64_sys_close
+4      common  stat                    __x64_sys_newstat
+5      common  fstat                   __x64_sys_newfstat
+6      common  lstat                   __x64_sys_newlstat
+7      common  poll                    __x64_sys_poll
+8      common  lseek                   __x64_sys_lseek
+9      common  mmap                    __x64_sys_mmap
+10     common  mprotect                __x64_sys_mprotect
+11     common  munmap                  __x64_sys_munmap
+12     common  brk                     __x64_sys_brk
+13     64      rt_sigaction            __x64_sys_rt_sigaction
+14     common  rt_sigprocmask          __x64_sys_rt_sigprocmask
+15     64      rt_sigreturn            __x64_sys_rt_sigreturn/ptregs
+16     64      ioctl                   __x64_sys_ioctl
+17     common  pread64                 __x64_sys_pread64
+18     common  pwrite64                __x64_sys_pwrite64
+19     64      readv                   __x64_sys_readv
+20     64      writev                  __x64_sys_writev
+21     common  access                  __x64_sys_access
+22     common  pipe                    __x64_sys_pipe
+23     common  select                  __x64_sys_select
+24     common  sched_yield             __x64_sys_sched_yield
+25     common  mremap                  __x64_sys_mremap
+26     common  msync                   __x64_sys_msync
+27     common  mincore                 __x64_sys_mincore
+28     common  madvise                 __x64_sys_madvise
+29     common  shmget                  __x64_sys_shmget
+30     common  shmat                   __x64_sys_shmat
+31     common  shmctl                  __x64_sys_shmctl
+32     common  dup                     __x64_sys_dup
+33     common  dup2                    __x64_sys_dup2
+34     common  pause                   __x64_sys_pause
+35     common  nanosleep               __x64_sys_nanosleep
+36     common  getitimer               __x64_sys_getitimer
+37     common  alarm                   __x64_sys_alarm
+38     common  setitimer               __x64_sys_setitimer
+39     common  getpid                  __x64_sys_getpid
+40     common  sendfile                __x64_sys_sendfile64
+41     common  socket                  __x64_sys_socket
+42     common  connect                 __x64_sys_connect
+43     common  accept                  __x64_sys_accept
+44     common  sendto                  __x64_sys_sendto
+45     64      recvfrom                __x64_sys_recvfrom
+46     64      sendmsg                 __x64_sys_sendmsg
+47     64      recvmsg                 __x64_sys_recvmsg
+48     common  shutdown                __x64_sys_shutdown
+49     common  bind                    __x64_sys_bind
+50     common  listen                  __x64_sys_listen
+51     common  getsockname             __x64_sys_getsockname
+52     common  getpeername             __x64_sys_getpeername
+53     common  socketpair              __x64_sys_socketpair
+54     64      setsockopt              __x64_sys_setsockopt
+55     64      getsockopt              __x64_sys_getsockopt
+56     common  clone                   __x64_sys_clone/ptregs
+57     common  fork                    __x64_sys_fork/ptregs
+58     common  vfork                   __x64_sys_vfork/ptregs
+59     64      execve                  __x64_sys_execve/ptregs
+60     common  exit                    __x64_sys_exit
+61     common  wait4                   __x64_sys_wait4
+62     common  kill                    __x64_sys_kill
+63     common  uname                   __x64_sys_newuname
+64     common  semget                  __x64_sys_semget
+65     common  semop                   __x64_sys_semop
+66     common  semctl                  __x64_sys_semctl
+67     common  shmdt                   __x64_sys_shmdt
+68     common  msgget                  __x64_sys_msgget
+69     common  msgsnd                  __x64_sys_msgsnd
+70     common  msgrcv                  __x64_sys_msgrcv
+71     common  msgctl                  __x64_sys_msgctl
+72     common  fcntl                   __x64_sys_fcntl
+73     common  flock                   __x64_sys_flock
+74     common  fsync                   __x64_sys_fsync
+75     common  fdatasync               __x64_sys_fdatasync
+76     common  truncate                __x64_sys_truncate
+77     common  ftruncate               __x64_sys_ftruncate
+78     common  getdents                __x64_sys_getdents
+79     common  getcwd                  __x64_sys_getcwd
+80     common  chdir                   __x64_sys_chdir
+81     common  fchdir                  __x64_sys_fchdir
+82     common  rename                  __x64_sys_rename
+83     common  mkdir                   __x64_sys_mkdir
+84     common  rmdir                   __x64_sys_rmdir
+85     common  creat                   __x64_sys_creat
+86     common  link                    __x64_sys_link
+87     common  unlink                  __x64_sys_unlink
+88     common  symlink                 __x64_sys_symlink
+89     common  readlink                __x64_sys_readlink
+90     common  chmod                   __x64_sys_chmod
+91     common  fchmod                  __x64_sys_fchmod
+92     common  chown                   __x64_sys_chown
+93     common  fchown                  __x64_sys_fchown
+94     common  lchown                  __x64_sys_lchown
+95     common  umask                   __x64_sys_umask
+96     common  gettimeofday            __x64_sys_gettimeofday
+97     common  getrlimit               __x64_sys_getrlimit
+98     common  getrusage               __x64_sys_getrusage
+99     common  sysinfo                 __x64_sys_sysinfo
+100    common  times                   __x64_sys_times
+101    64      ptrace                  __x64_sys_ptrace
+102    common  getuid                  __x64_sys_getuid
+103    common  syslog                  __x64_sys_syslog
+104    common  getgid                  __x64_sys_getgid
+105    common  setuid                  __x64_sys_setuid
+106    common  setgid                  __x64_sys_setgid
+107    common  geteuid                 __x64_sys_geteuid
+108    common  getegid                 __x64_sys_getegid
+109    common  setpgid                 __x64_sys_setpgid
+110    common  getppid                 __x64_sys_getppid
+111    common  getpgrp                 __x64_sys_getpgrp
+112    common  setsid                  __x64_sys_setsid
+113    common  setreuid                __x64_sys_setreuid
+114    common  setregid                __x64_sys_setregid
+115    common  getgroups               __x64_sys_getgroups
+116    common  setgroups               __x64_sys_setgroups
+117    common  setresuid               __x64_sys_setresuid
+118    common  getresuid               __x64_sys_getresuid
+119    common  setresgid               __x64_sys_setresgid
+120    common  getresgid               __x64_sys_getresgid
+121    common  getpgid                 __x64_sys_getpgid
+122    common  setfsuid                __x64_sys_setfsuid
+123    common  setfsgid                __x64_sys_setfsgid
+124    common  getsid                  __x64_sys_getsid
+125    common  capget                  __x64_sys_capget
+126    common  capset                  __x64_sys_capset
+127    64      rt_sigpending           __x64_sys_rt_sigpending
+128    64      rt_sigtimedwait         __x64_sys_rt_sigtimedwait
+129    64      rt_sigqueueinfo         __x64_sys_rt_sigqueueinfo
+130    common  rt_sigsuspend           __x64_sys_rt_sigsuspend
+131    64      sigaltstack             __x64_sys_sigaltstack
+132    common  utime                   __x64_sys_utime
+133    common  mknod                   __x64_sys_mknod
 134    64      uselib
-135    common  personality             sys_personality
-136    common  ustat                   sys_ustat
-137    common  statfs                  sys_statfs
-138    common  fstatfs                 sys_fstatfs
-139    common  sysfs                   sys_sysfs
-140    common  getpriority             sys_getpriority
-141    common  setpriority             sys_setpriority
-142    common  sched_setparam          sys_sched_setparam
-143    common  sched_getparam          sys_sched_getparam
-144    common  sched_setscheduler      sys_sched_setscheduler
-145    common  sched_getscheduler      sys_sched_getscheduler
-146    common  sched_get_priority_max  sys_sched_get_priority_max
-147    common  sched_get_priority_min  sys_sched_get_priority_min
-148    common  sched_rr_get_interval   sys_sched_rr_get_interval
-149    common  mlock                   sys_mlock
-150    common  munlock                 sys_munlock
-151    common  mlockall                sys_mlockall
-152    common  munlockall              sys_munlockall
-153    common  vhangup                 sys_vhangup
-154    common  modify_ldt              sys_modify_ldt
-155    common  pivot_root              sys_pivot_root
-156    64      _sysctl                 sys_sysctl
-157    common  prctl                   sys_prctl
-158    common  arch_prctl              sys_arch_prctl
-159    common  adjtimex                sys_adjtimex
-160    common  setrlimit               sys_setrlimit
-161    common  chroot                  sys_chroot
-162    common  sync                    sys_sync
-163    common  acct                    sys_acct
-164    common  settimeofday            sys_settimeofday
-165    common  mount                   sys_mount
-166    common  umount2                 sys_umount
-167    common  swapon                  sys_swapon
-168    common  swapoff                 sys_swapoff
-169    common  reboot                  sys_reboot
-170    common  sethostname             sys_sethostname
-171    common  setdomainname           sys_setdomainname
-172    common  iopl                    sys_iopl/ptregs
-173    common  ioperm                  sys_ioperm
+135    common  personality             __x64_sys_personality
+136    common  ustat                   __x64_sys_ustat
+137    common  statfs                  __x64_sys_statfs
+138    common  fstatfs                 __x64_sys_fstatfs
+139    common  sysfs                   __x64_sys_sysfs
+140    common  getpriority             __x64_sys_getpriority
+141    common  setpriority             __x64_sys_setpriority
+142    common  sched_setparam          __x64_sys_sched_setparam
+143    common  sched_getparam          __x64_sys_sched_getparam
+144    common  sched_setscheduler      __x64_sys_sched_setscheduler
+145    common  sched_getscheduler      __x64_sys_sched_getscheduler
+146    common  sched_get_priority_max  __x64_sys_sched_get_priority_max
+147    common  sched_get_priority_min  __x64_sys_sched_get_priority_min
+148    common  sched_rr_get_interval   __x64_sys_sched_rr_get_interval
+149    common  mlock                   __x64_sys_mlock
+150    common  munlock                 __x64_sys_munlock
+151    common  mlockall                __x64_sys_mlockall
+152    common  munlockall              __x64_sys_munlockall
+153    common  vhangup                 __x64_sys_vhangup
+154    common  modify_ldt              __x64_sys_modify_ldt
+155    common  pivot_root              __x64_sys_pivot_root
+156    64      _sysctl                 __x64_sys_sysctl
+157    common  prctl                   __x64_sys_prctl
+158    common  arch_prctl              __x64_sys_arch_prctl
+159    common  adjtimex                __x64_sys_adjtimex
+160    common  setrlimit               __x64_sys_setrlimit
+161    common  chroot                  __x64_sys_chroot
+162    common  sync                    __x64_sys_sync
+163    common  acct                    __x64_sys_acct
+164    common  settimeofday            __x64_sys_settimeofday
+165    common  mount                   __x64_sys_mount
+166    common  umount2                 __x64_sys_umount
+167    common  swapon                  __x64_sys_swapon
+168    common  swapoff                 __x64_sys_swapoff
+169    common  reboot                  __x64_sys_reboot
+170    common  sethostname             __x64_sys_sethostname
+171    common  setdomainname           __x64_sys_setdomainname
+172    common  iopl                    __x64_sys_iopl/ptregs
+173    common  ioperm                  __x64_sys_ioperm
 174    64      create_module
-175    common  init_module             sys_init_module
-176    common  delete_module           sys_delete_module
+175    common  init_module             __x64_sys_init_module
+176    common  delete_module           __x64_sys_delete_module
 177    64      get_kernel_syms
 178    64      query_module
-179    common  quotactl                sys_quotactl
+179    common  quotactl                __x64_sys_quotactl
 180    64      nfsservctl
 181    common  getpmsg
 182    common  putpmsg
 183    common  afs_syscall
 184    common  tuxcall
 185    common  security
-186    common  gettid                  sys_gettid
-187    common  readahead               sys_readahead
-188    common  setxattr                sys_setxattr
-189    common  lsetxattr               sys_lsetxattr
-190    common  fsetxattr               sys_fsetxattr
-191    common  getxattr                sys_getxattr
-192    common  lgetxattr               sys_lgetxattr
-193    common  fgetxattr               sys_fgetxattr
-194    common  listxattr               sys_listxattr
-195    common  llistxattr              sys_llistxattr
-196    common  flistxattr              sys_flistxattr
-197    common  removexattr             sys_removexattr
-198    common  lremovexattr            sys_lremovexattr
-199    common  fremovexattr            sys_fremovexattr
-200    common  tkill                   sys_tkill
-201    common  time                    sys_time
-202    common  futex                   sys_futex
-203    common  sched_setaffinity       sys_sched_setaffinity
-204    common  sched_getaffinity       sys_sched_getaffinity
+186    common  gettid                  __x64_sys_gettid
+187    common  readahead               __x64_sys_readahead
+188    common  setxattr                __x64_sys_setxattr
+189    common  lsetxattr               __x64_sys_lsetxattr
+190    common  fsetxattr               __x64_sys_fsetxattr
+191    common  getxattr                __x64_sys_getxattr
+192    common  lgetxattr               __x64_sys_lgetxattr
+193    common  fgetxattr               __x64_sys_fgetxattr
+194    common  listxattr               __x64_sys_listxattr
+195    common  llistxattr              __x64_sys_llistxattr
+196    common  flistxattr              __x64_sys_flistxattr
+197    common  removexattr             __x64_sys_removexattr
+198    common  lremovexattr            __x64_sys_lremovexattr
+199    common  fremovexattr            __x64_sys_fremovexattr
+200    common  tkill                   __x64_sys_tkill
+201    common  time                    __x64_sys_time
+202    common  futex                   __x64_sys_futex
+203    common  sched_setaffinity       __x64_sys_sched_setaffinity
+204    common  sched_getaffinity       __x64_sys_sched_getaffinity
 205    64      set_thread_area
-206    64      io_setup                sys_io_setup
-207    common  io_destroy              sys_io_destroy
-208    common  io_getevents            sys_io_getevents
-209    64      io_submit               sys_io_submit
-210    common  io_cancel               sys_io_cancel
+206    64      io_setup                __x64_sys_io_setup
+207    common  io_destroy              __x64_sys_io_destroy
+208    common  io_getevents            __x64_sys_io_getevents
+209    64      io_submit               __x64_sys_io_submit
+210    common  io_cancel               __x64_sys_io_cancel
 211    64      get_thread_area
-212    common  lookup_dcookie          sys_lookup_dcookie
-213    common  epoll_create            sys_epoll_create
+212    common  lookup_dcookie          __x64_sys_lookup_dcookie
+213    common  epoll_create            __x64_sys_epoll_create
 214    64      epoll_ctl_old
 215    64      epoll_wait_old
-216    common  remap_file_pages        sys_remap_file_pages
-217    common  getdents64              sys_getdents64
-218    common  set_tid_address         sys_set_tid_address
-219    common  restart_syscall         sys_restart_syscall
-220    common  semtimedop              sys_semtimedop
-221    common  fadvise64               sys_fadvise64
-222    64      timer_create            sys_timer_create
-223    common  timer_settime           sys_timer_settime
-224    common  timer_gettime           sys_timer_gettime
-225    common  timer_getoverrun        sys_timer_getoverrun
-226    common  timer_delete            sys_timer_delete
-227    common  clock_settime           sys_clock_settime
-228    common  clock_gettime           sys_clock_gettime
-229    common  clock_getres            sys_clock_getres
-230    common  clock_nanosleep         sys_clock_nanosleep
-231    common  exit_group              sys_exit_group
-232    common  epoll_wait              sys_epoll_wait
-233    common  epoll_ctl               sys_epoll_ctl
-234    common  tgkill                  sys_tgkill
-235    common  utimes                  sys_utimes
+216    common  remap_file_pages        __x64_sys_remap_file_pages
+217    common  getdents64              __x64_sys_getdents64
+218    common  set_tid_address         __x64_sys_set_tid_address
+219    common  restart_syscall         __x64_sys_restart_syscall
+220    common  semtimedop              __x64_sys_semtimedop
+221    common  fadvise64               __x64_sys_fadvise64
+222    64      timer_create            __x64_sys_timer_create
+223    common  timer_settime           __x64_sys_timer_settime
+224    common  timer_gettime           __x64_sys_timer_gettime
+225    common  timer_getoverrun        __x64_sys_timer_getoverrun
+226    common  timer_delete            __x64_sys_timer_delete
+227    common  clock_settime           __x64_sys_clock_settime
+228    common  clock_gettime           __x64_sys_clock_gettime
+229    common  clock_getres            __x64_sys_clock_getres
+230    common  clock_nanosleep         __x64_sys_clock_nanosleep
+231    common  exit_group              __x64_sys_exit_group
+232    common  epoll_wait              __x64_sys_epoll_wait
+233    common  epoll_ctl               __x64_sys_epoll_ctl
+234    common  tgkill                  __x64_sys_tgkill
+235    common  utimes                  __x64_sys_utimes
 236    64      vserver
-237    common  mbind                   sys_mbind
-238    common  set_mempolicy           sys_set_mempolicy
-239    common  get_mempolicy           sys_get_mempolicy
-240    common  mq_open                 sys_mq_open
-241    common  mq_unlink               sys_mq_unlink
-242    common  mq_timedsend            sys_mq_timedsend
-243    common  mq_timedreceive         sys_mq_timedreceive
-244    64      mq_notify               sys_mq_notify
-245    common  mq_getsetattr           sys_mq_getsetattr
-246    64      kexec_load              sys_kexec_load
-247    64      waitid                  sys_waitid
-248    common  add_key                 sys_add_key
-249    common  request_key             sys_request_key
-250    common  keyctl                  sys_keyctl
-251    common  ioprio_set              sys_ioprio_set
-252    common  ioprio_get              sys_ioprio_get
-253    common  inotify_init            sys_inotify_init
-254    common  inotify_add_watch       sys_inotify_add_watch
-255    common  inotify_rm_watch        sys_inotify_rm_watch
-256    common  migrate_pages           sys_migrate_pages
-257    common  openat                  sys_openat
-258    common  mkdirat                 sys_mkdirat
-259    common  mknodat                 sys_mknodat
-260    common  fchownat                sys_fchownat
-261    common  futimesat               sys_futimesat
-262    common  newfstatat              sys_newfstatat
-263    common  unlinkat                sys_unlinkat
-264    common  renameat                sys_renameat
-265    common  linkat                  sys_linkat
-266    common  symlinkat               sys_symlinkat
-267    common  readlinkat              sys_readlinkat
-268    common  fchmodat                sys_fchmodat
-269    common  faccessat               sys_faccessat
-270    common  pselect6                sys_pselect6
-271    common  ppoll                   sys_ppoll
-272    common  unshare                 sys_unshare
-273    64      set_robust_list         sys_set_robust_list
-274    64      get_robust_list         sys_get_robust_list
-275    common  splice                  sys_splice
-276    common  tee                     sys_tee
-277    common  sync_file_range         sys_sync_file_range
-278    64      vmsplice                sys_vmsplice
-279    64      move_pages              sys_move_pages
-280    common  utimensat               sys_utimensat
-281    common  epoll_pwait             sys_epoll_pwait
-282    common  signalfd                sys_signalfd
-283    common  timerfd_create          sys_timerfd_create
-284    common  eventfd                 sys_eventfd
-285    common  fallocate               sys_fallocate
-286    common  timerfd_settime         sys_timerfd_settime
-287    common  timerfd_gettime         sys_timerfd_gettime
-288    common  accept4                 sys_accept4
-289    common  signalfd4               sys_signalfd4
-290    common  eventfd2                sys_eventfd2
-291    common  epoll_create1           sys_epoll_create1
-292    common  dup3                    sys_dup3
-293    common  pipe2                   sys_pipe2
-294    common  inotify_init1           sys_inotify_init1
-295    64      preadv                  sys_preadv
-296    64      pwritev                 sys_pwritev
-297    64      rt_tgsigqueueinfo       sys_rt_tgsigqueueinfo
-298    common  perf_event_open         sys_perf_event_open
-299    64      recvmmsg                sys_recvmmsg
-300    common  fanotify_init           sys_fanotify_init
-301    common  fanotify_mark           sys_fanotify_mark
-302    common  prlimit64               sys_prlimit64
-303    common  name_to_handle_at       sys_name_to_handle_at
-304    common  open_by_handle_at       sys_open_by_handle_at
-305    common  clock_adjtime           sys_clock_adjtime
-306    common  syncfs                  sys_syncfs
-307    64      sendmmsg                sys_sendmmsg
-308    common  setns                   sys_setns
-309    common  getcpu                  sys_getcpu
-310    64      process_vm_readv        sys_process_vm_readv
-311    64      process_vm_writev       sys_process_vm_writev
-312    common  kcmp                    sys_kcmp
-313    common  finit_module            sys_finit_module
-314    common  sched_setattr           sys_sched_setattr
-315    common  sched_getattr           sys_sched_getattr
-316    common  renameat2               sys_renameat2
-317    common  seccomp                 sys_seccomp
-318    common  getrandom               sys_getrandom
-319    common  memfd_create            sys_memfd_create
-320    common  kexec_file_load         sys_kexec_file_load
-321    common  bpf                     sys_bpf
-322    64      execveat                sys_execveat/ptregs
-323    common  userfaultfd             sys_userfaultfd
-324    common  membarrier              sys_membarrier
-325    common  mlock2                  sys_mlock2
-326    common  copy_file_range         sys_copy_file_range
-327    64      preadv2                 sys_preadv2
-328    64      pwritev2                sys_pwritev2
-329    common  pkey_mprotect           sys_pkey_mprotect
-330    common  pkey_alloc              sys_pkey_alloc
-331    common  pkey_free               sys_pkey_free
-332    common  statx                   sys_statx
+237    common  mbind                   __x64_sys_mbind
+238    common  set_mempolicy           __x64_sys_set_mempolicy
+239    common  get_mempolicy           __x64_sys_get_mempolicy
+240    common  mq_open                 __x64_sys_mq_open
+241    common  mq_unlink               __x64_sys_mq_unlink
+242    common  mq_timedsend            __x64_sys_mq_timedsend
+243    common  mq_timedreceive         __x64_sys_mq_timedreceive
+244    64      mq_notify               __x64_sys_mq_notify
+245    common  mq_getsetattr           __x64_sys_mq_getsetattr
+246    64      kexec_load              __x64_sys_kexec_load
+247    64      waitid                  __x64_sys_waitid
+248    common  add_key                 __x64_sys_add_key
+249    common  request_key             __x64_sys_request_key
+250    common  keyctl                  __x64_sys_keyctl
+251    common  ioprio_set              __x64_sys_ioprio_set
+252    common  ioprio_get              __x64_sys_ioprio_get
+253    common  inotify_init            __x64_sys_inotify_init
+254    common  inotify_add_watch       __x64_sys_inotify_add_watch
+255    common  inotify_rm_watch        __x64_sys_inotify_rm_watch
+256    common  migrate_pages           __x64_sys_migrate_pages
+257    common  openat                  __x64_sys_openat
+258    common  mkdirat                 __x64_sys_mkdirat
+259    common  mknodat                 __x64_sys_mknodat
+260    common  fchownat                __x64_sys_fchownat
+261    common  futimesat               __x64_sys_futimesat
+262    common  newfstatat              __x64_sys_newfstatat
+263    common  unlinkat                __x64_sys_unlinkat
+264    common  renameat                __x64_sys_renameat
+265    common  linkat                  __x64_sys_linkat
+266    common  symlinkat               __x64_sys_symlinkat
+267    common  readlinkat              __x64_sys_readlinkat
+268    common  fchmodat                __x64_sys_fchmodat
+269    common  faccessat               __x64_sys_faccessat
+270    common  pselect6                __x64_sys_pselect6
+271    common  ppoll                   __x64_sys_ppoll
+272    common  unshare                 __x64_sys_unshare
+273    64      set_robust_list         __x64_sys_set_robust_list
+274    64      get_robust_list         __x64_sys_get_robust_list
+275    common  splice                  __x64_sys_splice
+276    common  tee                     __x64_sys_tee
+277    common  sync_file_range         __x64_sys_sync_file_range
+278    64      vmsplice                __x64_sys_vmsplice
+279    64      move_pages              __x64_sys_move_pages
+280    common  utimensat               __x64_sys_utimensat
+281    common  epoll_pwait             __x64_sys_epoll_pwait
+282    common  signalfd                __x64_sys_signalfd
+283    common  timerfd_create          __x64_sys_timerfd_create
+284    common  eventfd                 __x64_sys_eventfd
+285    common  fallocate               __x64_sys_fallocate
+286    common  timerfd_settime         __x64_sys_timerfd_settime
+287    common  timerfd_gettime         __x64_sys_timerfd_gettime
+288    common  accept4                 __x64_sys_accept4
+289    common  signalfd4               __x64_sys_signalfd4
+290    common  eventfd2                __x64_sys_eventfd2
+291    common  epoll_create1           __x64_sys_epoll_create1
+292    common  dup3                    __x64_sys_dup3
+293    common  pipe2                   __x64_sys_pipe2
+294    common  inotify_init1           __x64_sys_inotify_init1
+295    64      preadv                  __x64_sys_preadv
+296    64      pwritev                 __x64_sys_pwritev
+297    64      rt_tgsigqueueinfo       __x64_sys_rt_tgsigqueueinfo
+298    common  perf_event_open         __x64_sys_perf_event_open
+299    64      recvmmsg                __x64_sys_recvmmsg
+300    common  fanotify_init           __x64_sys_fanotify_init
+301    common  fanotify_mark           __x64_sys_fanotify_mark
+302    common  prlimit64               __x64_sys_prlimit64
+303    common  name_to_handle_at       __x64_sys_name_to_handle_at
+304    common  open_by_handle_at       __x64_sys_open_by_handle_at
+305    common  clock_adjtime           __x64_sys_clock_adjtime
+306    common  syncfs                  __x64_sys_syncfs
+307    64      sendmmsg                __x64_sys_sendmmsg
+308    common  setns                   __x64_sys_setns
+309    common  getcpu                  __x64_sys_getcpu
+310    64      process_vm_readv        __x64_sys_process_vm_readv
+311    64      process_vm_writev       __x64_sys_process_vm_writev
+312    common  kcmp                    __x64_sys_kcmp
+313    common  finit_module            __x64_sys_finit_module
+314    common  sched_setattr           __x64_sys_sched_setattr
+315    common  sched_getattr           __x64_sys_sched_getattr
+316    common  renameat2               __x64_sys_renameat2
+317    common  seccomp                 __x64_sys_seccomp
+318    common  getrandom               __x64_sys_getrandom
+319    common  memfd_create            __x64_sys_memfd_create
+320    common  kexec_file_load         __x64_sys_kexec_file_load
+321    common  bpf                     __x64_sys_bpf
+322    64      execveat                __x64_sys_execveat/ptregs
+323    common  userfaultfd             __x64_sys_userfaultfd
+324    common  membarrier              __x64_sys_membarrier
+325    common  mlock2                  __x64_sys_mlock2
+326    common  copy_file_range         __x64_sys_copy_file_range
+327    64      preadv2                 __x64_sys_preadv2
+328    64      pwritev2                __x64_sys_pwritev2
+329    common  pkey_mprotect           __x64_sys_pkey_mprotect
+330    common  pkey_alloc              __x64_sys_pkey_alloc
+331    common  pkey_free               __x64_sys_pkey_free
+332    common  statx                   __x64_sys_statx
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
-# for native 64-bit operation.
+# for native 64-bit operation. The __x32_compat_sys stubs are created
+# on-the-fly for compat_sys_*() compatibility system calls if X86_X32
+# is defined.
 #
-512    x32     rt_sigaction            compat_sys_rt_sigaction
+512    x32     rt_sigaction            __x32_compat_sys_rt_sigaction
 513    x32     rt_sigreturn            sys32_x32_rt_sigreturn
-514    x32     ioctl                   compat_sys_ioctl
-515    x32     readv                   compat_sys_readv
-516    x32     writev                  compat_sys_writev
-517    x32     recvfrom                compat_sys_recvfrom
-518    x32     sendmsg                 compat_sys_sendmsg
-519    x32     recvmsg                 compat_sys_recvmsg
-520    x32     execve                  compat_sys_execve/ptregs
-521    x32     ptrace                  compat_sys_ptrace
-522    x32     rt_sigpending           compat_sys_rt_sigpending
-523    x32     rt_sigtimedwait         compat_sys_rt_sigtimedwait
-524    x32     rt_sigqueueinfo         compat_sys_rt_sigqueueinfo
-525    x32     sigaltstack             compat_sys_sigaltstack
-526    x32     timer_create            compat_sys_timer_create
-527    x32     mq_notify               compat_sys_mq_notify
-528    x32     kexec_load              compat_sys_kexec_load
-529    x32     waitid                  compat_sys_waitid
-530    x32     set_robust_list         compat_sys_set_robust_list
-531    x32     get_robust_list         compat_sys_get_robust_list
-532    x32     vmsplice                compat_sys_vmsplice
-533    x32     move_pages              compat_sys_move_pages
-534    x32     preadv                  compat_sys_preadv64
-535    x32     pwritev                 compat_sys_pwritev64
-536    x32     rt_tgsigqueueinfo       compat_sys_rt_tgsigqueueinfo
-537    x32     recvmmsg                compat_sys_recvmmsg
-538    x32     sendmmsg                compat_sys_sendmmsg
-539    x32     process_vm_readv        compat_sys_process_vm_readv
-540    x32     process_vm_writev       compat_sys_process_vm_writev
-541    x32     setsockopt              compat_sys_setsockopt
-542    x32     getsockopt              compat_sys_getsockopt
-543    x32     io_setup                compat_sys_io_setup
-544    x32     io_submit               compat_sys_io_submit
-545    x32     execveat                compat_sys_execveat/ptregs
-546    x32     preadv2                 compat_sys_preadv64v2
-547    x32     pwritev2                compat_sys_pwritev64v2
+514    x32     ioctl                   __x32_compat_sys_ioctl
+515    x32     readv                   __x32_compat_sys_readv
+516    x32     writev                  __x32_compat_sys_writev
+517    x32     recvfrom                __x32_compat_sys_recvfrom
+518    x32     sendmsg                 __x32_compat_sys_sendmsg
+519    x32     recvmsg                 __x32_compat_sys_recvmsg
+520    x32     execve                  __x32_compat_sys_execve/ptregs
+521    x32     ptrace                  __x32_compat_sys_ptrace
+522    x32     rt_sigpending           __x32_compat_sys_rt_sigpending
+523    x32     rt_sigtimedwait         __x32_compat_sys_rt_sigtimedwait
+524    x32     rt_sigqueueinfo         __x32_compat_sys_rt_sigqueueinfo
+525    x32     sigaltstack             __x32_compat_sys_sigaltstack
+526    x32     timer_create            __x32_compat_sys_timer_create
+527    x32     mq_notify               __x32_compat_sys_mq_notify
+528    x32     kexec_load              __x32_compat_sys_kexec_load
+529    x32     waitid                  __x32_compat_sys_waitid
+530    x32     set_robust_list         __x32_compat_sys_set_robust_list
+531    x32     get_robust_list         __x32_compat_sys_get_robust_list
+532    x32     vmsplice                __x32_compat_sys_vmsplice
+533    x32     move_pages              __x32_compat_sys_move_pages
+534    x32     preadv                  __x32_compat_sys_preadv64
+535    x32     pwritev                 __x32_compat_sys_pwritev64
+536    x32     rt_tgsigqueueinfo       __x32_compat_sys_rt_tgsigqueueinfo
+537    x32     recvmmsg                __x32_compat_sys_recvmmsg
+538    x32     sendmmsg                __x32_compat_sys_sendmmsg
+539    x32     process_vm_readv        __x32_compat_sys_process_vm_readv
+540    x32     process_vm_writev       __x32_compat_sys_process_vm_writev
+541    x32     setsockopt              __x32_compat_sys_setsockopt
+542    x32     getsockopt              __x32_compat_sys_getsockopt
+543    x32     io_setup                __x32_compat_sys_io_setup
+544    x32     io_submit               __x32_compat_sys_io_submit
+545    x32     execveat                __x32_compat_sys_execveat/ptregs
+546    x32     preadv2                 __x32_compat_sys_preadv64v2
+547    x32     pwritev2                __x32_compat_sys_pwritev64v2
index 4aca13f..1c41b4e 100644 (file)
@@ -439,7 +439,7 @@ int cmd_help(int argc, const char **argv)
 #ifdef HAVE_LIBELF_SUPPORT
                "probe",
 #endif
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
                "trace",
 #endif
        NULL };
index 5065646..57393e9 100644 (file)
@@ -83,7 +83,7 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
        };
 
        argc = parse_options(argc, argv, options, record_mem_usage,
-                            PARSE_OPT_STOP_AT_NON_OPTION);
+                            PARSE_OPT_KEEP_UNKNOWN);
 
        rec_argc = argc + 9; /* max number of arguments */
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
@@ -436,7 +436,7 @@ int cmd_mem(int argc, const char **argv)
        }
 
        argc = parse_options_subcommand(argc, argv, mem_options, mem_subcommands,
-                                       mem_usage, PARSE_OPT_STOP_AT_NON_OPTION);
+                                       mem_usage, PARSE_OPT_KEEP_UNKNOWN);
 
        if (!argc || !(strncmp(argv[0], "rec", 3) || mem.operation))
                usage_with_options(mem_usage, mem_options);
index 313c424..e0a9845 100644 (file)
@@ -657,8 +657,11 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,
                        break;
                case PERF_RECORD_SWITCH:
                case PERF_RECORD_SWITCH_CPU_WIDE:
-                       if (has(SWITCH_OUT))
+                       if (has(SWITCH_OUT)) {
                                ret += fprintf(fp, "S");
+                               if (sample->misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT)
+                                       ret += fprintf(fp, "p");
+                       }
                default:
                        break;
                }
@@ -2801,11 +2804,11 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
        for_each_lang(scripts_path, scripts_dir, lang_dirent) {
                scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
                          lang_dirent->d_name);
-#ifdef NO_LIBPERL
+#ifndef HAVE_LIBPERL_SUPPORT
                if (strstr(lang_path, "perl"))
                        continue;
 #endif
-#ifdef NO_LIBPYTHON
+#ifndef HAVE_LIBPYTHON_SUPPORT
                if (strstr(lang_path, "python"))
                        continue;
 #endif
index f5c4548..147a27e 100644 (file)
@@ -1943,7 +1943,8 @@ static const struct option stat_options[] = {
        OPT_STRING(0, "post", &post_cmd, "command",
                        "command to run after to the measured command"),
        OPT_UINTEGER('I', "interval-print", &stat_config.interval,
-                   "print counts at regular interval in ms (>= 10)"),
+                   "print counts at regular interval in ms "
+                   "(overhead is possible for values <= 100ms)"),
        OPT_INTEGER(0, "interval-count", &stat_config.times,
                    "print counts for fixed number of times"),
        OPT_UINTEGER(0, "timeout", &stat_config.timeout,
@@ -2923,17 +2924,6 @@ int cmd_stat(int argc, const char **argv)
                }
        }
 
-       if (interval && interval < 100) {
-               if (interval < 10) {
-                       pr_err("print interval must be >= 10ms\n");
-                       parse_options_usage(stat_usage, stat_options, "I", 1);
-                       goto out;
-               } else
-                       pr_warning("print interval < 100ms. "
-                                  "The overhead percentage could be high in some cases. "
-                                  "Please proceed with caution.\n");
-       }
-
        if (stat_config.times && interval)
                interval_count = true;
        else if (stat_config.times && !interval) {
index 2abe391..50df168 100644 (file)
@@ -60,7 +60,10 @@ static void library_status(void)
        STATUS(HAVE_DWARF_GETLOCATIONS_SUPPORT, dwarf_getlocations);
        STATUS(HAVE_GLIBC_SUPPORT, glibc);
        STATUS(HAVE_GTK2_SUPPORT, gtk2);
+#ifndef HAVE_SYSCALL_TABLE_SUPPORT
        STATUS(HAVE_LIBAUDIT_SUPPORT, libaudit);
+#endif
+       STATUS(HAVE_SYSCALL_TABLE_SUPPORT, syscall_table);
        STATUS(HAVE_LIBBFD_SUPPORT, libbfd);
        STATUS(HAVE_LIBELF_SUPPORT, libelf);
        STATUS(HAVE_LIBNUMA_SUPPORT, libnuma);
index 1659029..20a08cb 100644 (file)
@@ -73,7 +73,7 @@ static struct cmd_struct commands[] = {
        { "lock",       cmd_lock,       0 },
        { "kvm",        cmd_kvm,        0 },
        { "test",       cmd_test,       0 },
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
        { "trace",      cmd_trace,      0 },
 #endif
        { "inject",     cmd_inject,     0 },
@@ -491,7 +491,7 @@ int main(int argc, const char **argv)
                argv[0] = cmd;
        }
        if (strstarts(cmd, "trace")) {
-#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
+#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
                setup_path();
                argv[0] = "trace";
                return cmd_trace(argc, argv);
index e4123c1..1ca5106 100644 (file)
@@ -31,7 +31,7 @@ struct bpf_map_def SEC("maps") flip_table = {
        .max_entries = 1,
 };
 
-SEC("func=SyS_epoll_pwait")
+SEC("func=do_epoll_wait")
 int bpf_func__SyS_epoll_pwait(void *ctx)
 {
        int ind =0;
index 3626924..ff3ec83 100644 (file)
@@ -9,7 +9,6 @@
 #define SEC(NAME) __attribute__((section(NAME), used))
 
 #include <uapi/linux/fs.h>
-#include <uapi/asm/ptrace.h>
 
 SEC("func=vfs_llseek")
 int bpf_func__vfs_llseek(void *ctx)
index 625f5a6..cac8f88 100644 (file)
@@ -118,6 +118,7 @@ static struct test generic_tests[] = {
        {
                .desc = "Breakpoint accounting",
                .func = test__bp_accounting,
+               .is_supported = test__bp_signal_is_supported,
        },
        {
                .desc = "Number of exit events of a simple workload",
index bb8e6bc..0919b07 100644 (file)
@@ -75,7 +75,7 @@ int test__basic_mmap(struct test *test __maybe_unused, int subtest __maybe_unuse
                snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]);
                evsels[i] = perf_evsel__newtp("syscalls", name);
                if (IS_ERR(evsels[i])) {
-                       pr_debug("perf_evsel__new\n");
+                       pr_debug("perf_evsel__new(%s)\n", name);
                        goto out_delete_evlist;
                }
 
index 417e3ec..9f68077 100644 (file)
@@ -54,6 +54,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
        P_MMAP_FLAG(EXECUTABLE);
        P_MMAP_FLAG(FILE);
        P_MMAP_FLAG(FIXED);
+#ifdef MAP_FIXED_NOREPLACE
+       P_MMAP_FLAG(FIXED_NOREPLACE);
+#endif
        P_MMAP_FLAG(GROWSDOWN);
        P_MMAP_FLAG(HUGETLB);
        P_MMAP_FLAG(LOCKED);
index 12c099a..3781d74 100644 (file)
@@ -692,6 +692,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
                "J             Toggle showing number of jump sources on targets\n"
                "n             Search next string\n"
                "o             Toggle disassembler output/simplified view\n"
+               "O             Bump offset level (jump targets -> +call -> all -> cycle thru)\n"
                "s             Toggle source code view\n"
                "t             Circulate percent, total period, samples view\n"
                "/             Search string\n"
@@ -719,6 +720,10 @@ static int annotate_browser__run(struct annotate_browser *browser,
                        notes->options->use_offset = !notes->options->use_offset;
                        annotation__update_column_widths(notes);
                        continue;
+               case 'O':
+                       if (++notes->options->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
+                               notes->options->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
+                       continue;
                case 'j':
                        notes->options->jump_arrows = !notes->options->jump_arrows;
                        continue;
index 0eec06c..e5f2472 100644 (file)
@@ -2714,7 +2714,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
        "h/?/F1        Show this window\n"                              \
        "UP/DOWN/PGUP\n"                                                \
        "PGDN/SPACE    Navigate\n"                                      \
-       "q/ESC/CTRL+C  Exit browser\n\n"                                \
+       "q/ESC/CTRL+C  Exit browser or go back to previous screen\n\n"  \
        "For multiple event sessions:\n\n"                              \
        "TAB/UNTAB     Switch events\n\n"                               \
        "For symbolic views (--sort has sym):\n\n"                      \
index fbad8df..536ee14 100644 (file)
@@ -46,6 +46,7 @@
 struct annotation_options annotation__default_options = {
        .use_offset     = true,
        .jump_arrows    = true,
+       .offset_level   = ANNOTATION__OFFSET_JUMP_TARGETS,
 };
 
 const char     *disassembler_style;
@@ -2512,7 +2513,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                if (!notes->options->use_offset) {
                        printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
                } else {
-                       if (al->jump_sources) {
+                       if (al->jump_sources &&
+                           notes->options->offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) {
                                if (notes->options->show_nr_jumps) {
                                        int prev;
                                        printed = scnprintf(bf, sizeof(bf), "%*d ",
@@ -2523,9 +2525,14 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
                                        obj__printf(obj, bf);
                                        obj__set_color(obj, prev);
                                }
-
+print_addr:
                                printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
                                                    notes->widths.target, addr);
+                       } else if (ins__is_call(&disasm_line(al)->ins) &&
+                                  notes->options->offset_level >= ANNOTATION__OFFSET_CALL) {
+                               goto print_addr;
+                       } else if (notes->options->offset_level == ANNOTATION__MAX_OFFSET_LEVEL) {
+                               goto print_addr;
                        } else {
                                printed = scnprintf(bf, sizeof(bf), "%-*s  ",
                                                    notes->widths.addr, " ");
@@ -2642,10 +2649,11 @@ int __annotation__scnprintf_samples_period(struct annotation *notes,
  */
 static struct annotation_config {
        const char *name;
-       bool *value;
+       void *value;
 } annotation__configs[] = {
        ANNOTATION__CFG(hide_src_code),
        ANNOTATION__CFG(jump_arrows),
+       ANNOTATION__CFG(offset_level),
        ANNOTATION__CFG(show_linenr),
        ANNOTATION__CFG(show_nr_jumps),
        ANNOTATION__CFG(show_nr_samples),
@@ -2677,8 +2685,16 @@ static int annotation__config(const char *var, const char *value,
 
        if (cfg == NULL)
                pr_debug("%s variable unknown, ignoring...", var);
-       else
-               *cfg->value = perf_config_bool(name, value);
+       else if (strcmp(var, "annotate.offset_level") == 0) {
+               perf_config_int(cfg->value, name, value);
+
+               if (*(int *)cfg->value > ANNOTATION__MAX_OFFSET_LEVEL)
+                       *(int *)cfg->value = ANNOTATION__MAX_OFFSET_LEVEL;
+               else if (*(int *)cfg->value < ANNOTATION__MIN_OFFSET_LEVEL)
+                       *(int *)cfg->value = ANNOTATION__MIN_OFFSET_LEVEL;
+       } else {
+               *(bool *)cfg->value = perf_config_bool(name, value);
+       }
        return 0;
 }
 
index db8d09b..f28a9e4 100644 (file)
@@ -70,8 +70,17 @@ struct annotation_options {
             show_nr_jumps,
             show_nr_samples,
             show_total_period;
+       u8   offset_level;
 };
 
+enum {
+       ANNOTATION__OFFSET_JUMP_TARGETS = 1,
+       ANNOTATION__OFFSET_CALL,
+       ANNOTATION__MAX_OFFSET_LEVEL,
+};
+
+#define ANNOTATION__MIN_OFFSET_LEVEL ANNOTATION__OFFSET_JUMP_TARGETS
+
 extern struct annotation_options annotation__default_options;
 
 struct annotation;
index 640af88..c8b98fa 100644 (file)
@@ -1,6 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * SPDX-License-Identifier: GPL-2.0
- *
  * Copyright(C) 2015-2018 Linaro Limited.
  *
  * Author: Tor Jeremiassen <tor@ti.com>
index 1b0d422..40020b1 100644 (file)
@@ -1,6 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
- * SPDX-License-Identifier: GPL-2.0
- *
  * Copyright(C) 2015-2018 Linaro Limited.
  *
  * Author: Tor Jeremiassen <tor@ti.com>
index 5864d5d..37f8d48 100644 (file)
@@ -1,18 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright(C) 2015 Linaro Limited. All rights reserved.
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifndef INCLUDE__UTIL_PERF_CS_ETM_H__
index f0a6cbd..98ff3a6 100644 (file)
@@ -1421,7 +1421,9 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp)
 {
        bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT;
-       const char *in_out = out ? "OUT" : "IN ";
+       const char *in_out = !out ? "IN         " :
+               !(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT) ?
+                                   "OUT        " : "OUT preempt";
 
        if (event->header.type == PERF_RECORD_SWITCH)
                return fprintf(fp, " %s\n", in_out);
index 1ac8d92..3e87486 100644 (file)
@@ -2870,8 +2870,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 #if defined(__i386__) || defined(__x86_64__)
                if (evsel->attr.type == PERF_TYPE_HARDWARE)
                        return scnprintf(msg, size, "%s",
-       "No hardware sampling interrupt available.\n"
-       "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.");
+       "No hardware sampling interrupt available.\n");
 #endif
                break;
        case EBUSY:
@@ -2894,8 +2893,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
 
        return scnprintf(msg, size,
        "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n"
-       "/bin/dmesg may provide additional information.\n"
-       "No CONFIG_PERF_EVENTS=y kernel support configured?",
+       "/bin/dmesg | grep -i perf may provide additional information.\n",
                         err, str_error_r(err, sbuf, sizeof(sbuf)),
                         perf_evsel__name(evsel));
 }
index ff17920..c3cef36 100755 (executable)
@@ -38,7 +38,7 @@ do
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
 
-echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)"
+echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)"
 sed -n -e 's/^perf-\([^        ]*\)[   ].* audit*/\1/p' command-list.txt |
 sort |
 while read cmd
index 121df16..a8bff21 100644 (file)
@@ -1320,7 +1320,8 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
 
        dir = opendir(path);
        if (!dir) {
-               pr_warning("failed: can't open node sysfs data\n");
+               pr_debug2("%s: could't read %s, does this arch have topology information?\n",
+                         __func__, path);
                return -1;
        }
 
index 064bdcb..61a5e50 100644 (file)
@@ -562,6 +562,12 @@ static int is_pmu_core(const char *name)
        if (stat(path, &st) == 0)
                return 1;
 
+       /* Look for cpu sysfs (specific to s390) */
+       scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s",
+                 sysfs, name);
+       if (stat(path, &st) == 0 && !strncmp(name, "cpum_", 5))
+               return 1;
+
        return 0;
 }
 
index 62b2dd2..1466814 100644 (file)
@@ -2091,16 +2091,14 @@ static bool symbol__read_kptr_restrict(void)
 
 int symbol__annotation_init(void)
 {
+       if (symbol_conf.init_annotation)
+               return 0;
+
        if (symbol_conf.initialized) {
                pr_err("Annotation needs to be init before symbol__init()\n");
                return -1;
        }
 
-       if (symbol_conf.init_annotation) {
-               pr_warning("Annotation being initialized multiple times\n");
-               return 0;
-       }
-
        symbol_conf.priv_size += sizeof(struct annotation);
        symbol_conf.init_annotation = true;
        return 0;
index 895122d..0ee7f56 100644 (file)
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <linux/compiler.h>
 
-#ifdef HAVE_SYSCALL_TABLE
+#ifdef HAVE_SYSCALL_TABLE_SUPPORT
 #include <string.h>
 #include "string2.h"
 #include "util.h"
@@ -139,7 +139,7 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
 
-#else /* HAVE_SYSCALL_TABLE */
+#else /* HAVE_SYSCALL_TABLE_SUPPORT */
 
 #include <libaudit.h>
 
@@ -176,4 +176,4 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
 {
        return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
 }
-#endif /* HAVE_SYSCALL_TABLE */
+#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
index 0ac9077..b1e5c3a 100644 (file)
@@ -98,7 +98,7 @@ static void register_python_scripting(struct scripting_ops *scripting_ops)
        }
 }
 
-#ifdef NO_LIBPYTHON
+#ifndef HAVE_LIBPYTHON_SUPPORT
 void setup_python_scripting(void)
 {
        register_python_scripting(&python_scripting_unsupported_ops);
@@ -161,7 +161,7 @@ static void register_perl_scripting(struct scripting_ops *scripting_ops)
        }
 }
 
-#ifdef NO_LIBPERL
+#ifndef HAVE_LIBPERL_SUPPORT
 void setup_perl_scripting(void)
 {
        register_perl_scripting(&perl_scripting_unsupported_ops);
index cb166be..4ea385b 100644 (file)
@@ -138,6 +138,7 @@ static u32 handle[] = {
 };
 
 static unsigned long dimm_fail_cmd_flags[NUM_DCR];
+static int dimm_fail_cmd_code[NUM_DCR];
 
 struct nfit_test_fw {
        enum intel_fw_update_state state;
@@ -892,8 +893,11 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
        if (i >= ARRAY_SIZE(handle))
                return -ENXIO;
 
-       if ((1 << func) & dimm_fail_cmd_flags[i])
+       if ((1 << func) & dimm_fail_cmd_flags[i]) {
+               if (dimm_fail_cmd_code[i])
+                       return dimm_fail_cmd_code[i];
                return -EIO;
+       }
 
        return i;
 }
@@ -1162,12 +1166,12 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state)
 
 static void put_dimms(void *data)
 {
-       struct device **dimm_dev = data;
+       struct nfit_test *t = data;
        int i;
 
-       for (i = 0; i < NUM_DCR; i++)
-               if (dimm_dev[i])
-                       device_unregister(dimm_dev[i]);
+       for (i = 0; i < t->num_dcr; i++)
+               if (t->dimm_dev[i])
+                       device_unregister(t->dimm_dev[i]);
 }
 
 static struct class *nfit_test_dimm;
@@ -1176,13 +1180,11 @@ static int dimm_name_to_id(struct device *dev)
 {
        int dimm;
 
-       if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
-                       || dimm >= NUM_DCR || dimm < 0)
+       if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1)
                return -ENXIO;
        return dimm;
 }
 
-
 static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
                char *buf)
 {
@@ -1191,7 +1193,7 @@ static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
        if (dimm < 0)
                return dimm;
 
-       return sprintf(buf, "%#x", handle[dimm]);
+       return sprintf(buf, "%#x\n", handle[dimm]);
 }
 DEVICE_ATTR_RO(handle);
 
@@ -1225,8 +1227,39 @@ static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RW(fail_cmd);
 
+static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       int dimm = dimm_name_to_id(dev);
+
+       if (dimm < 0)
+               return dimm;
+
+       return sprintf(buf, "%d\n", dimm_fail_cmd_code[dimm]);
+}
+
+static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t size)
+{
+       int dimm = dimm_name_to_id(dev);
+       unsigned long val;
+       ssize_t rc;
+
+       if (dimm < 0)
+               return dimm;
+
+       rc = kstrtol(buf, 0, &val);
+       if (rc)
+               return rc;
+
+       dimm_fail_cmd_code[dimm] = val;
+       return size;
+}
+static DEVICE_ATTR_RW(fail_cmd_code);
+
 static struct attribute *nfit_test_dimm_attributes[] = {
        &dev_attr_fail_cmd.attr,
+       &dev_attr_fail_cmd_code.attr,
        &dev_attr_handle.attr,
        NULL,
 };
@@ -1240,6 +1273,23 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
        NULL,
 };
 
+static int nfit_test_dimm_init(struct nfit_test *t)
+{
+       int i;
+
+       if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t))
+               return -ENOMEM;
+       for (i = 0; i < t->num_dcr; i++) {
+               t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
+                               &t->pdev.dev, 0, NULL,
+                               nfit_test_dimm_attribute_groups,
+                               "test_dimm%d", i + t->dcr_idx);
+               if (!t->dimm_dev[i])
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
 static void smart_init(struct nfit_test *t)
 {
        int i;
@@ -1335,17 +1385,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
        if (!t->_fit)
                return -ENOMEM;
 
-       if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
+       if (nfit_test_dimm_init(t))
                return -ENOMEM;
-       for (i = 0; i < NUM_DCR; i++) {
-               t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
-                               &t->pdev.dev, 0, NULL,
-                               nfit_test_dimm_attribute_groups,
-                               "test_dimm%d", i);
-               if (!t->dimm_dev[i])
-                       return -ENOMEM;
-       }
-
        smart_init(t);
        return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
@@ -1377,6 +1418,8 @@ static int nfit_test1_alloc(struct nfit_test *t)
        if (!t->spa_set[1])
                return -ENOMEM;
 
+       if (nfit_test_dimm_init(t))
+               return -ENOMEM;
        smart_init(t);
        return ars_state_init(&t->pdev.dev, &t->ars_state);
 }
@@ -2222,6 +2265,9 @@ static void nfit_test1_setup(struct nfit_test *t)
        set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
        set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
        set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
+       set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
 }
 
 static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
index 4e6d09f..5c7d700 100644 (file)
@@ -1,8 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
-TEST_PROGS := dnotify_test devpts_pts
-all: $(TEST_PROGS)
 
-include ../lib.mk
+TEST_GEN_PROGS := devpts_pts
+TEST_GEN_PROGS_EXTENDED := dnotify_test
 
-clean:
-       rm -fr $(TEST_PROGS)
+include ../lib.mk
index dc44de9..2ddcc96 100644 (file)
@@ -4,17 +4,18 @@ top_srcdir = ../../../../
 UNAME_M := $(shell uname -m)
 
 LIBKVM = lib/assert.c lib/elf.c lib/io.c lib/kvm_util.c lib/sparsebit.c
-LIBKVM_x86_64 = lib/x86.c
+LIBKVM_x86_64 = lib/x86.c lib/vmx.c
 
 TEST_GEN_PROGS_x86_64 = set_sregs_test
 TEST_GEN_PROGS_x86_64 += sync_regs_test
+TEST_GEN_PROGS_x86_64 += vmx_tsc_adjust_test
 
 TEST_GEN_PROGS += $(TEST_GEN_PROGS_$(UNAME_M))
 LIBKVM += $(LIBKVM_$(UNAME_M))
 
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
-CFLAGS += -O2 -g -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
+CFLAGS += -O2 -g -std=gnu99 -I$(LINUX_HDR_PATH) -Iinclude -I$(<D)
 
 # After inclusion, $(OUTPUT) is defined and
 # $(TEST_GEN_PROGS) starts with $(OUTPUT)/
index 57974ad..637b701 100644 (file)
@@ -112,24 +112,27 @@ void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
 vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
        vm_paddr_t paddr_min, uint32_t memslot);
 
-void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid);
+struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
 void vcpu_set_cpuid(
        struct kvm_vm *vm, uint32_t vcpuid, struct kvm_cpuid2 *cpuid);
 
-struct kvm_cpuid2 *allocate_kvm_cpuid2(void);
 struct kvm_cpuid_entry2 *
-find_cpuid_index_entry(struct kvm_cpuid2 *cpuid, uint32_t function,
-                      uint32_t index);
+kvm_get_supported_cpuid_index(uint32_t function, uint32_t index);
 
 static inline struct kvm_cpuid_entry2 *
-find_cpuid_entry(struct kvm_cpuid2 *cpuid, uint32_t function)
+kvm_get_supported_cpuid_entry(uint32_t function)
 {
-       return find_cpuid_index_entry(cpuid, function, 0);
+       return kvm_get_supported_cpuid_index(function, 0);
 }
 
 struct kvm_vm *vm_create_default(uint32_t vcpuid, void *guest_code);
 void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code);
 
+typedef void (*vmx_guest_code_t)(vm_vaddr_t vmxon_vaddr,
+                                vm_paddr_t vmxon_paddr,
+                                vm_vaddr_t vmcs_vaddr,
+                                vm_paddr_t vmcs_paddr);
+
 struct kvm_userspace_memory_region *
 kvm_userspace_memory_region_find(struct kvm_vm *vm, uint64_t start,
                                 uint64_t end);
diff --git a/tools/testing/selftests/kvm/include/vmx.h b/tools/testing/selftests/kvm/include/vmx.h
new file mode 100644 (file)
index 0000000..6ed8499
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * tools/testing/selftests/kvm/include/vmx.h
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ */
+
+#ifndef SELFTEST_KVM_VMX_H
+#define SELFTEST_KVM_VMX_H
+
+#include <stdint.h>
+#include "x86.h"
+
+#define CPUID_VMX_BIT                          5
+
+#define CPUID_VMX                              (1 << 5)
+
+/*
+ * Definitions of Primary Processor-Based VM-Execution Controls.
+ */
+#define CPU_BASED_VIRTUAL_INTR_PENDING         0x00000004
+#define CPU_BASED_USE_TSC_OFFSETING            0x00000008
+#define CPU_BASED_HLT_EXITING                  0x00000080
+#define CPU_BASED_INVLPG_EXITING               0x00000200
+#define CPU_BASED_MWAIT_EXITING                        0x00000400
+#define CPU_BASED_RDPMC_EXITING                        0x00000800
+#define CPU_BASED_RDTSC_EXITING                        0x00001000
+#define CPU_BASED_CR3_LOAD_EXITING             0x00008000
+#define CPU_BASED_CR3_STORE_EXITING            0x00010000
+#define CPU_BASED_CR8_LOAD_EXITING             0x00080000
+#define CPU_BASED_CR8_STORE_EXITING            0x00100000
+#define CPU_BASED_TPR_SHADOW                   0x00200000
+#define CPU_BASED_VIRTUAL_NMI_PENDING          0x00400000
+#define CPU_BASED_MOV_DR_EXITING               0x00800000
+#define CPU_BASED_UNCOND_IO_EXITING            0x01000000
+#define CPU_BASED_USE_IO_BITMAPS               0x02000000
+#define CPU_BASED_MONITOR_TRAP                 0x08000000
+#define CPU_BASED_USE_MSR_BITMAPS              0x10000000
+#define CPU_BASED_MONITOR_EXITING              0x20000000
+#define CPU_BASED_PAUSE_EXITING                        0x40000000
+#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS  0x80000000
+
+#define CPU_BASED_ALWAYSON_WITHOUT_TRUE_MSR    0x0401e172
+
+/*
+ * Definitions of Secondary Processor-Based VM-Execution Controls.
+ */
+#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
+#define SECONDARY_EXEC_ENABLE_EPT              0x00000002
+#define SECONDARY_EXEC_DESC                    0x00000004
+#define SECONDARY_EXEC_RDTSCP                  0x00000008
+#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE  0x00000010
+#define SECONDARY_EXEC_ENABLE_VPID             0x00000020
+#define SECONDARY_EXEC_WBINVD_EXITING          0x00000040
+#define SECONDARY_EXEC_UNRESTRICTED_GUEST      0x00000080
+#define SECONDARY_EXEC_APIC_REGISTER_VIRT      0x00000100
+#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY   0x00000200
+#define SECONDARY_EXEC_PAUSE_LOOP_EXITING      0x00000400
+#define SECONDARY_EXEC_RDRAND_EXITING          0x00000800
+#define SECONDARY_EXEC_ENABLE_INVPCID          0x00001000
+#define SECONDARY_EXEC_ENABLE_VMFUNC           0x00002000
+#define SECONDARY_EXEC_SHADOW_VMCS             0x00004000
+#define SECONDARY_EXEC_RDSEED_EXITING          0x00010000
+#define SECONDARY_EXEC_ENABLE_PML              0x00020000
+#define SECONDARY_EPT_VE                       0x00040000
+#define SECONDARY_ENABLE_XSAV_RESTORE          0x00100000
+#define SECONDARY_EXEC_TSC_SCALING             0x02000000
+
+#define PIN_BASED_EXT_INTR_MASK                        0x00000001
+#define PIN_BASED_NMI_EXITING                  0x00000008
+#define PIN_BASED_VIRTUAL_NMIS                 0x00000020
+#define PIN_BASED_VMX_PREEMPTION_TIMER         0x00000040
+#define PIN_BASED_POSTED_INTR                  0x00000080
+
+#define PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR    0x00000016
+
+#define VM_EXIT_SAVE_DEBUG_CONTROLS            0x00000004
+#define VM_EXIT_HOST_ADDR_SPACE_SIZE           0x00000200
+#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL     0x00001000
+#define VM_EXIT_ACK_INTR_ON_EXIT               0x00008000
+#define VM_EXIT_SAVE_IA32_PAT                  0x00040000
+#define VM_EXIT_LOAD_IA32_PAT                  0x00080000
+#define VM_EXIT_SAVE_IA32_EFER                 0x00100000
+#define VM_EXIT_LOAD_IA32_EFER                 0x00200000
+#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER      0x00400000
+
+#define VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR      0x00036dff
+
+#define VM_ENTRY_LOAD_DEBUG_CONTROLS           0x00000004
+#define VM_ENTRY_IA32E_MODE                    0x00000200
+#define VM_ENTRY_SMM                           0x00000400
+#define VM_ENTRY_DEACT_DUAL_MONITOR            0x00000800
+#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL    0x00002000
+#define VM_ENTRY_LOAD_IA32_PAT                 0x00004000
+#define VM_ENTRY_LOAD_IA32_EFER                        0x00008000
+
+#define VM_ENTRY_ALWAYSON_WITHOUT_TRUE_MSR     0x000011ff
+
+#define VMX_MISC_PREEMPTION_TIMER_RATE_MASK    0x0000001f
+#define VMX_MISC_SAVE_EFER_LMA                 0x00000020
+
+#define EXIT_REASON_FAILED_VMENTRY     0x80000000
+#define EXIT_REASON_EXCEPTION_NMI      0
+#define EXIT_REASON_EXTERNAL_INTERRUPT 1
+#define EXIT_REASON_TRIPLE_FAULT       2
+#define EXIT_REASON_PENDING_INTERRUPT  7
+#define EXIT_REASON_NMI_WINDOW         8
+#define EXIT_REASON_TASK_SWITCH                9
+#define EXIT_REASON_CPUID              10
+#define EXIT_REASON_HLT                        12
+#define EXIT_REASON_INVD               13
+#define EXIT_REASON_INVLPG             14
+#define EXIT_REASON_RDPMC              15
+#define EXIT_REASON_RDTSC              16
+#define EXIT_REASON_VMCALL             18
+#define EXIT_REASON_VMCLEAR            19
+#define EXIT_REASON_VMLAUNCH           20
+#define EXIT_REASON_VMPTRLD            21
+#define EXIT_REASON_VMPTRST            22
+#define EXIT_REASON_VMREAD             23
+#define EXIT_REASON_VMRESUME           24
+#define EXIT_REASON_VMWRITE            25
+#define EXIT_REASON_VMOFF              26
+#define EXIT_REASON_VMON               27
+#define EXIT_REASON_CR_ACCESS          28
+#define EXIT_REASON_DR_ACCESS          29
+#define EXIT_REASON_IO_INSTRUCTION     30
+#define EXIT_REASON_MSR_READ           31
+#define EXIT_REASON_MSR_WRITE          32
+#define EXIT_REASON_INVALID_STATE      33
+#define EXIT_REASON_MWAIT_INSTRUCTION  36
+#define EXIT_REASON_MONITOR_INSTRUCTION 39
+#define EXIT_REASON_PAUSE_INSTRUCTION  40
+#define EXIT_REASON_MCE_DURING_VMENTRY 41
+#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
+#define EXIT_REASON_APIC_ACCESS                44
+#define EXIT_REASON_EOI_INDUCED                45
+#define EXIT_REASON_EPT_VIOLATION      48
+#define EXIT_REASON_EPT_MISCONFIG      49
+#define EXIT_REASON_INVEPT             50
+#define EXIT_REASON_RDTSCP             51
+#define EXIT_REASON_PREEMPTION_TIMER   52
+#define EXIT_REASON_INVVPID            53
+#define EXIT_REASON_WBINVD             54
+#define EXIT_REASON_XSETBV             55
+#define EXIT_REASON_APIC_WRITE         56
+#define EXIT_REASON_INVPCID            58
+#define EXIT_REASON_PML_FULL           62
+#define EXIT_REASON_XSAVES             63
+#define EXIT_REASON_XRSTORS            64
+#define LAST_EXIT_REASON               64
+
+enum vmcs_field {
+       VIRTUAL_PROCESSOR_ID            = 0x00000000,
+       POSTED_INTR_NV                  = 0x00000002,
+       GUEST_ES_SELECTOR               = 0x00000800,
+       GUEST_CS_SELECTOR               = 0x00000802,
+       GUEST_SS_SELECTOR               = 0x00000804,
+       GUEST_DS_SELECTOR               = 0x00000806,
+       GUEST_FS_SELECTOR               = 0x00000808,
+       GUEST_GS_SELECTOR               = 0x0000080a,
+       GUEST_LDTR_SELECTOR             = 0x0000080c,
+       GUEST_TR_SELECTOR               = 0x0000080e,
+       GUEST_INTR_STATUS               = 0x00000810,
+       GUEST_PML_INDEX                 = 0x00000812,
+       HOST_ES_SELECTOR                = 0x00000c00,
+       HOST_CS_SELECTOR                = 0x00000c02,
+       HOST_SS_SELECTOR                = 0x00000c04,
+       HOST_DS_SELECTOR                = 0x00000c06,
+       HOST_FS_SELECTOR                = 0x00000c08,
+       HOST_GS_SELECTOR                = 0x00000c0a,
+       HOST_TR_SELECTOR                = 0x00000c0c,
+       IO_BITMAP_A                     = 0x00002000,
+       IO_BITMAP_A_HIGH                = 0x00002001,
+       IO_BITMAP_B                     = 0x00002002,
+       IO_BITMAP_B_HIGH                = 0x00002003,
+       MSR_BITMAP                      = 0x00002004,
+       MSR_BITMAP_HIGH                 = 0x00002005,
+       VM_EXIT_MSR_STORE_ADDR          = 0x00002006,
+       VM_EXIT_MSR_STORE_ADDR_HIGH     = 0x00002007,
+       VM_EXIT_MSR_LOAD_ADDR           = 0x00002008,
+       VM_EXIT_MSR_LOAD_ADDR_HIGH      = 0x00002009,
+       VM_ENTRY_MSR_LOAD_ADDR          = 0x0000200a,
+       VM_ENTRY_MSR_LOAD_ADDR_HIGH     = 0x0000200b,
+       PML_ADDRESS                     = 0x0000200e,
+       PML_ADDRESS_HIGH                = 0x0000200f,
+       TSC_OFFSET                      = 0x00002010,
+       TSC_OFFSET_HIGH                 = 0x00002011,
+       VIRTUAL_APIC_PAGE_ADDR          = 0x00002012,
+       VIRTUAL_APIC_PAGE_ADDR_HIGH     = 0x00002013,
+       APIC_ACCESS_ADDR                = 0x00002014,
+       APIC_ACCESS_ADDR_HIGH           = 0x00002015,
+       POSTED_INTR_DESC_ADDR           = 0x00002016,
+       POSTED_INTR_DESC_ADDR_HIGH      = 0x00002017,
+       EPT_POINTER                     = 0x0000201a,
+       EPT_POINTER_HIGH                = 0x0000201b,
+       EOI_EXIT_BITMAP0                = 0x0000201c,
+       EOI_EXIT_BITMAP0_HIGH           = 0x0000201d,
+       EOI_EXIT_BITMAP1                = 0x0000201e,
+       EOI_EXIT_BITMAP1_HIGH           = 0x0000201f,
+       EOI_EXIT_BITMAP2                = 0x00002020,
+       EOI_EXIT_BITMAP2_HIGH           = 0x00002021,
+       EOI_EXIT_BITMAP3                = 0x00002022,
+       EOI_EXIT_BITMAP3_HIGH           = 0x00002023,
+       VMREAD_BITMAP                   = 0x00002026,
+       VMREAD_BITMAP_HIGH              = 0x00002027,
+       VMWRITE_BITMAP                  = 0x00002028,
+       VMWRITE_BITMAP_HIGH             = 0x00002029,
+       XSS_EXIT_BITMAP                 = 0x0000202C,
+       XSS_EXIT_BITMAP_HIGH            = 0x0000202D,
+       TSC_MULTIPLIER                  = 0x00002032,
+       TSC_MULTIPLIER_HIGH             = 0x00002033,
+       GUEST_PHYSICAL_ADDRESS          = 0x00002400,
+       GUEST_PHYSICAL_ADDRESS_HIGH     = 0x00002401,
+       VMCS_LINK_POINTER               = 0x00002800,
+       VMCS_LINK_POINTER_HIGH          = 0x00002801,
+       GUEST_IA32_DEBUGCTL             = 0x00002802,
+       GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
+       GUEST_IA32_PAT                  = 0x00002804,
+       GUEST_IA32_PAT_HIGH             = 0x00002805,
+       GUEST_IA32_EFER                 = 0x00002806,
+       GUEST_IA32_EFER_HIGH            = 0x00002807,
+       GUEST_IA32_PERF_GLOBAL_CTRL     = 0x00002808,
+       GUEST_IA32_PERF_GLOBAL_CTRL_HIGH= 0x00002809,
+       GUEST_PDPTR0                    = 0x0000280a,
+       GUEST_PDPTR0_HIGH               = 0x0000280b,
+       GUEST_PDPTR1                    = 0x0000280c,
+       GUEST_PDPTR1_HIGH               = 0x0000280d,
+       GUEST_PDPTR2                    = 0x0000280e,
+       GUEST_PDPTR2_HIGH               = 0x0000280f,
+       GUEST_PDPTR3                    = 0x00002810,
+       GUEST_PDPTR3_HIGH               = 0x00002811,
+       GUEST_BNDCFGS                   = 0x00002812,
+       GUEST_BNDCFGS_HIGH              = 0x00002813,
+       HOST_IA32_PAT                   = 0x00002c00,
+       HOST_IA32_PAT_HIGH              = 0x00002c01,
+       HOST_IA32_EFER                  = 0x00002c02,
+       HOST_IA32_EFER_HIGH             = 0x00002c03,
+       HOST_IA32_PERF_GLOBAL_CTRL      = 0x00002c04,
+       HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
+       PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
+       CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
+       EXCEPTION_BITMAP                = 0x00004004,
+       PAGE_FAULT_ERROR_CODE_MASK      = 0x00004006,
+       PAGE_FAULT_ERROR_CODE_MATCH     = 0x00004008,
+       CR3_TARGET_COUNT                = 0x0000400a,
+       VM_EXIT_CONTROLS                = 0x0000400c,
+       VM_EXIT_MSR_STORE_COUNT         = 0x0000400e,
+       VM_EXIT_MSR_LOAD_COUNT          = 0x00004010,
+       VM_ENTRY_CONTROLS               = 0x00004012,
+       VM_ENTRY_MSR_LOAD_COUNT         = 0x00004014,
+       VM_ENTRY_INTR_INFO_FIELD        = 0x00004016,
+       VM_ENTRY_EXCEPTION_ERROR_CODE   = 0x00004018,
+       VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
+       TPR_THRESHOLD                   = 0x0000401c,
+       SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
+       PLE_GAP                         = 0x00004020,
+       PLE_WINDOW                      = 0x00004022,
+       VM_INSTRUCTION_ERROR            = 0x00004400,
+       VM_EXIT_REASON                  = 0x00004402,
+       VM_EXIT_INTR_INFO               = 0x00004404,
+       VM_EXIT_INTR_ERROR_CODE         = 0x00004406,
+       IDT_VECTORING_INFO_FIELD        = 0x00004408,
+       IDT_VECTORING_ERROR_CODE        = 0x0000440a,
+       VM_EXIT_INSTRUCTION_LEN         = 0x0000440c,
+       VMX_INSTRUCTION_INFO            = 0x0000440e,
+       GUEST_ES_LIMIT                  = 0x00004800,
+       GUEST_CS_LIMIT                  = 0x00004802,
+       GUEST_SS_LIMIT                  = 0x00004804,
+       GUEST_DS_LIMIT                  = 0x00004806,
+       GUEST_FS_LIMIT                  = 0x00004808,
+       GUEST_GS_LIMIT                  = 0x0000480a,
+       GUEST_LDTR_LIMIT                = 0x0000480c,
+       GUEST_TR_LIMIT                  = 0x0000480e,
+       GUEST_GDTR_LIMIT                = 0x00004810,
+       GUEST_IDTR_LIMIT                = 0x00004812,
+       GUEST_ES_AR_BYTES               = 0x00004814,
+       GUEST_CS_AR_BYTES               = 0x00004816,
+       GUEST_SS_AR_BYTES               = 0x00004818,
+       GUEST_DS_AR_BYTES               = 0x0000481a,
+       GUEST_FS_AR_BYTES               = 0x0000481c,
+       GUEST_GS_AR_BYTES               = 0x0000481e,
+       GUEST_LDTR_AR_BYTES             = 0x00004820,
+       GUEST_TR_AR_BYTES               = 0x00004822,
+       GUEST_INTERRUPTIBILITY_INFO     = 0x00004824,
+       GUEST_ACTIVITY_STATE            = 0X00004826,
+       GUEST_SYSENTER_CS               = 0x0000482A,
+       VMX_PREEMPTION_TIMER_VALUE      = 0x0000482E,
+       HOST_IA32_SYSENTER_CS           = 0x00004c00,
+       CR0_GUEST_HOST_MASK             = 0x00006000,
+       CR4_GUEST_HOST_MASK             = 0x00006002,
+       CR0_READ_SHADOW                 = 0x00006004,
+       CR4_READ_SHADOW                 = 0x00006006,
+       CR3_TARGET_VALUE0               = 0x00006008,
+       CR3_TARGET_VALUE1               = 0x0000600a,
+       CR3_TARGET_VALUE2               = 0x0000600c,
+       CR3_TARGET_VALUE3               = 0x0000600e,
+       EXIT_QUALIFICATION              = 0x00006400,
+       GUEST_LINEAR_ADDRESS            = 0x0000640a,
+       GUEST_CR0                       = 0x00006800,
+       GUEST_CR3                       = 0x00006802,
+       GUEST_CR4                       = 0x00006804,
+       GUEST_ES_BASE                   = 0x00006806,
+       GUEST_CS_BASE                   = 0x00006808,
+       GUEST_SS_BASE                   = 0x0000680a,
+       GUEST_DS_BASE                   = 0x0000680c,
+       GUEST_FS_BASE                   = 0x0000680e,
+       GUEST_GS_BASE                   = 0x00006810,
+       GUEST_LDTR_BASE                 = 0x00006812,
+       GUEST_TR_BASE                   = 0x00006814,
+       GUEST_GDTR_BASE                 = 0x00006816,
+       GUEST_IDTR_BASE                 = 0x00006818,
+       GUEST_DR7                       = 0x0000681a,
+       GUEST_RSP                       = 0x0000681c,
+       GUEST_RIP                       = 0x0000681e,
+       GUEST_RFLAGS                    = 0x00006820,
+       GUEST_PENDING_DBG_EXCEPTIONS    = 0x00006822,
+       GUEST_SYSENTER_ESP              = 0x00006824,
+       GUEST_SYSENTER_EIP              = 0x00006826,
+       HOST_CR0                        = 0x00006c00,
+       HOST_CR3                        = 0x00006c02,
+       HOST_CR4                        = 0x00006c04,
+       HOST_FS_BASE                    = 0x00006c06,
+       HOST_GS_BASE                    = 0x00006c08,
+       HOST_TR_BASE                    = 0x00006c0a,
+       HOST_GDTR_BASE                  = 0x00006c0c,
+       HOST_IDTR_BASE                  = 0x00006c0e,
+       HOST_IA32_SYSENTER_ESP          = 0x00006c10,
+       HOST_IA32_SYSENTER_EIP          = 0x00006c12,
+       HOST_RSP                        = 0x00006c14,
+       HOST_RIP                        = 0x00006c16,
+};
+
+struct vmx_msr_entry {
+       uint32_t index;
+       uint32_t reserved;
+       uint64_t value;
+} __attribute__ ((aligned(16)));
+
+static inline int vmxon(uint64_t phys)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmxon %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(phys)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline void vmxoff(void)
+{
+       __asm__ __volatile__("vmxoff");
+}
+
+static inline int vmclear(uint64_t vmcs_pa)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmclear %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(vmcs_pa)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline int vmptrld(uint64_t vmcs_pa)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmptrld %[pa]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [pa]"m"(vmcs_pa)
+               : "cc", "memory");
+
+       return ret;
+}
+
+/*
+ * No guest state (e.g. GPRs) is established by this vmlaunch.
+ */
+static inline int vmlaunch(void)
+{
+       int ret;
+
+       __asm__ __volatile__("push %%rbp;"
+                            "push %%rcx;"
+                            "push %%rdx;"
+                            "push %%rsi;"
+                            "push %%rdi;"
+                            "push $0;"
+                            "vmwrite %%rsp, %[host_rsp];"
+                            "lea 1f(%%rip), %%rax;"
+                            "vmwrite %%rax, %[host_rip];"
+                            "vmlaunch;"
+                            "incq (%%rsp);"
+                            "1: pop %%rax;"
+                            "pop %%rdi;"
+                            "pop %%rsi;"
+                            "pop %%rdx;"
+                            "pop %%rcx;"
+                            "pop %%rbp;"
+                            : [ret]"=&a"(ret)
+                            : [host_rsp]"r"((uint64_t)HOST_RSP),
+                              [host_rip]"r"((uint64_t)HOST_RIP)
+                            : "memory", "cc", "rbx", "r8", "r9", "r10",
+                              "r11", "r12", "r13", "r14", "r15");
+       return ret;
+}
+
+/*
+ * No guest state (e.g. GPRs) is established by this vmresume.
+ */
+static inline int vmresume(void)
+{
+       int ret;
+
+       __asm__ __volatile__("push %%rbp;"
+                            "push %%rcx;"
+                            "push %%rdx;"
+                            "push %%rsi;"
+                            "push %%rdi;"
+                            "push $0;"
+                            "vmwrite %%rsp, %[host_rsp];"
+                            "lea 1f(%%rip), %%rax;"
+                            "vmwrite %%rax, %[host_rip];"
+                            "vmresume;"
+                            "incq (%%rsp);"
+                            "1: pop %%rax;"
+                            "pop %%rdi;"
+                            "pop %%rsi;"
+                            "pop %%rdx;"
+                            "pop %%rcx;"
+                            "pop %%rbp;"
+                            : [ret]"=&a"(ret)
+                            : [host_rsp]"r"((uint64_t)HOST_RSP),
+                              [host_rip]"r"((uint64_t)HOST_RIP)
+                            : "memory", "cc", "rbx", "r8", "r9", "r10",
+                              "r11", "r12", "r13", "r14", "r15");
+       return ret;
+}
+
+static inline int vmread(uint64_t encoding, uint64_t *value)
+{
+       uint64_t tmp;
+       uint8_t ret;
+
+       __asm__ __volatile__("vmread %[encoding], %[value]; setna %[ret]"
+               : [value]"=rm"(tmp), [ret]"=rm"(ret)
+               : [encoding]"r"(encoding)
+               : "cc", "memory");
+
+       *value = tmp;
+       return ret;
+}
+
+/*
+ * A wrapper around vmread that ignores errors and returns zero if the
+ * vmread instruction fails.
+ */
+static inline uint64_t vmreadz(uint64_t encoding)
+{
+       uint64_t value = 0;
+       vmread(encoding, &value);
+       return value;
+}
+
+static inline int vmwrite(uint64_t encoding, uint64_t value)
+{
+       uint8_t ret;
+
+       __asm__ __volatile__ ("vmwrite %[value], %[encoding]; setna %[ret]"
+               : [ret]"=rm"(ret)
+               : [value]"rm"(value), [encoding]"r"(encoding)
+               : "cc", "memory");
+
+       return ret;
+}
+
+static inline uint32_t vmcs_revision(void)
+{
+       return rdmsr(MSR_IA32_VMX_BASIC);
+}
+
+void prepare_for_vmx_operation(void);
+void prepare_vmcs(void *guest_rip, void *guest_rsp);
+struct kvm_vm *vm_create_default_vmx(uint32_t vcpuid,
+                                    vmx_guest_code_t guest_code);
+
+#endif /* !SELFTEST_KVM_VMX_H */
index 7ca1bb4..2cedfda 100644 (file)
@@ -378,7 +378,7 @@ int kvm_memcmp_hva_gva(void *hva,
  * complicated. This function uses a reasonable default length for
  * the array and performs the appropriate allocation.
  */
-struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
+static struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
 {
        struct kvm_cpuid2 *cpuid;
        int nent = 100;
@@ -402,17 +402,21 @@ struct kvm_cpuid2 *allocate_kvm_cpuid2(void)
  * Input Args: None
  *
  * Output Args:
- *   cpuid - The supported KVM CPUID
  *
- * Return: void
+ * Return: The supported KVM CPUID
  *
  * Get the guest CPUID supported by KVM.
  */
-void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
+struct kvm_cpuid2 *kvm_get_supported_cpuid(void)
 {
+       static struct kvm_cpuid2 *cpuid;
        int ret;
        int kvm_fd;
 
+       if (cpuid)
+               return cpuid;
+
+       cpuid = allocate_kvm_cpuid2();
        kvm_fd = open(KVM_DEV_PATH, O_RDONLY);
        TEST_ASSERT(kvm_fd >= 0, "open %s failed, rc: %i errno: %i",
                KVM_DEV_PATH, kvm_fd, errno);
@@ -422,6 +426,7 @@ void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
                    ret, errno);
 
        close(kvm_fd);
+       return cpuid;
 }
 
 /* Locate a cpuid entry.
@@ -435,12 +440,13 @@ void kvm_get_supported_cpuid(struct kvm_cpuid2 *cpuid)
  * Return: A pointer to the cpuid entry. Never returns NULL.
  */
 struct kvm_cpuid_entry2 *
-find_cpuid_index_entry(struct kvm_cpuid2 *cpuid, uint32_t function,
-                      uint32_t index)
+kvm_get_supported_cpuid_index(uint32_t function, uint32_t index)
 {
+       struct kvm_cpuid2 *cpuid;
        struct kvm_cpuid_entry2 *entry = NULL;
        int i;
 
+       cpuid = kvm_get_supported_cpuid();
        for (i = 0; i < cpuid->nent; i++) {
                if (cpuid->entries[i].function == function &&
                    cpuid->entries[i].index == index) {
@@ -1435,7 +1441,7 @@ vm_paddr_t vm_phy_page_alloc(struct kvm_vm *vm,
        sparsebit_idx_t pg;
 
        TEST_ASSERT((paddr_min % vm->page_size) == 0, "Min physical address "
-               "not divisable by page size.\n"
+               "not divisible by page size.\n"
                "  paddr_min: 0x%lx page_size: 0x%x",
                paddr_min, vm->page_size);
 
index 0c5cf3e..b132bc9 100644 (file)
  *     avoided by moving the setting of the nodes mask bits into
  *     the previous nodes num_after setting.
  *
- *   + Node starting index is evenly divisable by the number of bits
+ *   + Node starting index is evenly divisible by the number of bits
  *     within a nodes mask member.
  *
  *   + Nodes never represent a range of bits that wrap around the
@@ -1741,7 +1741,7 @@ void sparsebit_validate_internal(struct sparsebit *s)
 
                /* Validate node index is divisible by the mask size */
                if (nodep->idx % MASK_BITS) {
-                       fprintf(stderr, "Node index not divisable by "
+                       fprintf(stderr, "Node index not divisible by "
                                "mask size,\n"
                                "  nodep: %p nodep->idx: 0x%lx "
                                "MASK_BITS: %lu\n",
diff --git a/tools/testing/selftests/kvm/lib/vmx.c b/tools/testing/selftests/kvm/lib/vmx.c
new file mode 100644 (file)
index 0000000..0231bc0
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * tools/testing/selftests/kvm/lib/x86.c
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ */
+
+#define _GNU_SOURCE /* for program_invocation_name */
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "x86.h"
+#include "vmx.h"
+
+/* Create a default VM for VMX tests.
+ *
+ * Input Args:
+ *   vcpuid - The id of the single VCPU to add to the VM.
+ *   guest_code - The vCPU's entry point
+ *
+ * Output Args: None
+ *
+ * Return:
+ *   Pointer to opaque structure that describes the created VM.
+ */
+struct kvm_vm *
+vm_create_default_vmx(uint32_t vcpuid, vmx_guest_code_t guest_code)
+{
+       struct kvm_cpuid2 *cpuid;
+       struct kvm_vm *vm;
+       vm_vaddr_t vmxon_vaddr;
+       vm_paddr_t vmxon_paddr;
+       vm_vaddr_t vmcs_vaddr;
+       vm_paddr_t vmcs_paddr;
+
+       vm = vm_create_default(vcpuid, (void *) guest_code);
+
+       /* Enable nesting in CPUID */
+       vcpu_set_cpuid(vm, vcpuid, kvm_get_supported_cpuid());
+
+       /* Setup of a region of guest memory for the vmxon region. */
+       vmxon_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
+       vmxon_paddr = addr_gva2gpa(vm, vmxon_vaddr);
+
+       /* Setup of a region of guest memory for a vmcs. */
+       vmcs_vaddr = vm_vaddr_alloc(vm, getpagesize(), 0, 0, 0);
+       vmcs_paddr = addr_gva2gpa(vm, vmcs_vaddr);
+
+       vcpu_args_set(vm, vcpuid, 4, vmxon_vaddr, vmxon_paddr, vmcs_vaddr,
+                     vmcs_paddr);
+
+       return vm;
+}
+
+void prepare_for_vmx_operation(void)
+{
+       uint64_t feature_control;
+       uint64_t required;
+       unsigned long cr0;
+       unsigned long cr4;
+
+       /*
+        * Ensure bits in CR0 and CR4 are valid in VMX operation:
+        * - Bit X is 1 in _FIXED0: bit X is fixed to 1 in CRx.
+        * - Bit X is 0 in _FIXED1: bit X is fixed to 0 in CRx.
+        */
+       __asm__ __volatile__("mov %%cr0, %0" : "=r"(cr0) : : "memory");
+       cr0 &= rdmsr(MSR_IA32_VMX_CR0_FIXED1);
+       cr0 |= rdmsr(MSR_IA32_VMX_CR0_FIXED0);
+       __asm__ __volatile__("mov %0, %%cr0" : : "r"(cr0) : "memory");
+
+       __asm__ __volatile__("mov %%cr4, %0" : "=r"(cr4) : : "memory");
+       cr4 &= rdmsr(MSR_IA32_VMX_CR4_FIXED1);
+       cr4 |= rdmsr(MSR_IA32_VMX_CR4_FIXED0);
+       /* Enable VMX operation */
+       cr4 |= X86_CR4_VMXE;
+       __asm__ __volatile__("mov %0, %%cr4" : : "r"(cr4) : "memory");
+
+       /*
+        * Configure IA32_FEATURE_CONTROL MSR to allow VMXON:
+        *  Bit 0: Lock bit. If clear, VMXON causes a #GP.
+        *  Bit 2: Enables VMXON outside of SMX operation. If clear, VMXON
+        *    outside of SMX causes a #GP.
+        */
+       required = FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
+       required |= FEATURE_CONTROL_LOCKED;
+       feature_control = rdmsr(MSR_IA32_FEATURE_CONTROL);
+       if ((feature_control & required) != required)
+               wrmsr(MSR_IA32_FEATURE_CONTROL, feature_control | required);
+}
+
+/*
+ * Initialize the control fields to the most basic settings possible.
+ */
+static inline void init_vmcs_control_fields(void)
+{
+       vmwrite(VIRTUAL_PROCESSOR_ID, 0);
+       vmwrite(POSTED_INTR_NV, 0);
+
+       vmwrite(PIN_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PINBASED_CTLS));
+       vmwrite(CPU_BASED_VM_EXEC_CONTROL, rdmsr(MSR_IA32_VMX_PROCBASED_CTLS));
+       vmwrite(EXCEPTION_BITMAP, 0);
+       vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
+       vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, -1); /* Never match */
+       vmwrite(CR3_TARGET_COUNT, 0);
+       vmwrite(VM_EXIT_CONTROLS, rdmsr(MSR_IA32_VMX_EXIT_CTLS) |
+               VM_EXIT_HOST_ADDR_SPACE_SIZE);    /* 64-bit host */
+       vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
+       vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
+       vmwrite(VM_ENTRY_CONTROLS, rdmsr(MSR_IA32_VMX_ENTRY_CTLS) |
+               VM_ENTRY_IA32E_MODE);             /* 64-bit guest */
+       vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
+       vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
+       vmwrite(TPR_THRESHOLD, 0);
+       vmwrite(SECONDARY_VM_EXEC_CONTROL, 0);
+
+       vmwrite(CR0_GUEST_HOST_MASK, 0);
+       vmwrite(CR4_GUEST_HOST_MASK, 0);
+       vmwrite(CR0_READ_SHADOW, get_cr0());
+       vmwrite(CR4_READ_SHADOW, get_cr4());
+}
+
+/*
+ * Initialize the host state fields based on the current host state, with
+ * the exception of HOST_RSP and HOST_RIP, which should be set by vmlaunch
+ * or vmresume.
+ */
+static inline void init_vmcs_host_state(void)
+{
+       uint32_t exit_controls = vmreadz(VM_EXIT_CONTROLS);
+
+       vmwrite(HOST_ES_SELECTOR, get_es());
+       vmwrite(HOST_CS_SELECTOR, get_cs());
+       vmwrite(HOST_SS_SELECTOR, get_ss());
+       vmwrite(HOST_DS_SELECTOR, get_ds());
+       vmwrite(HOST_FS_SELECTOR, get_fs());
+       vmwrite(HOST_GS_SELECTOR, get_gs());
+       vmwrite(HOST_TR_SELECTOR, get_tr());
+
+       if (exit_controls & VM_EXIT_LOAD_IA32_PAT)
+               vmwrite(HOST_IA32_PAT, rdmsr(MSR_IA32_CR_PAT));
+       if (exit_controls & VM_EXIT_LOAD_IA32_EFER)
+               vmwrite(HOST_IA32_EFER, rdmsr(MSR_EFER));
+       if (exit_controls & VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL)
+               vmwrite(HOST_IA32_PERF_GLOBAL_CTRL,
+                       rdmsr(MSR_CORE_PERF_GLOBAL_CTRL));
+
+       vmwrite(HOST_IA32_SYSENTER_CS, rdmsr(MSR_IA32_SYSENTER_CS));
+
+       vmwrite(HOST_CR0, get_cr0());
+       vmwrite(HOST_CR3, get_cr3());
+       vmwrite(HOST_CR4, get_cr4());
+       vmwrite(HOST_FS_BASE, rdmsr(MSR_FS_BASE));
+       vmwrite(HOST_GS_BASE, rdmsr(MSR_GS_BASE));
+       vmwrite(HOST_TR_BASE,
+               get_desc64_base((struct desc64 *)(get_gdt_base() + get_tr())));
+       vmwrite(HOST_GDTR_BASE, get_gdt_base());
+       vmwrite(HOST_IDTR_BASE, get_idt_base());
+       vmwrite(HOST_IA32_SYSENTER_ESP, rdmsr(MSR_IA32_SYSENTER_ESP));
+       vmwrite(HOST_IA32_SYSENTER_EIP, rdmsr(MSR_IA32_SYSENTER_EIP));
+}
+
+/*
+ * Initialize the guest state fields essentially as a clone of
+ * the host state fields. Some host state fields have fixed
+ * values, and we set the corresponding guest state fields accordingly.
+ */
+static inline void init_vmcs_guest_state(void *rip, void *rsp)
+{
+       vmwrite(GUEST_ES_SELECTOR, vmreadz(HOST_ES_SELECTOR));
+       vmwrite(GUEST_CS_SELECTOR, vmreadz(HOST_CS_SELECTOR));
+       vmwrite(GUEST_SS_SELECTOR, vmreadz(HOST_SS_SELECTOR));
+       vmwrite(GUEST_DS_SELECTOR, vmreadz(HOST_DS_SELECTOR));
+       vmwrite(GUEST_FS_SELECTOR, vmreadz(HOST_FS_SELECTOR));
+       vmwrite(GUEST_GS_SELECTOR, vmreadz(HOST_GS_SELECTOR));
+       vmwrite(GUEST_LDTR_SELECTOR, 0);
+       vmwrite(GUEST_TR_SELECTOR, vmreadz(HOST_TR_SELECTOR));
+       vmwrite(GUEST_INTR_STATUS, 0);
+       vmwrite(GUEST_PML_INDEX, 0);
+
+       vmwrite(VMCS_LINK_POINTER, -1ll);
+       vmwrite(GUEST_IA32_DEBUGCTL, 0);
+       vmwrite(GUEST_IA32_PAT, vmreadz(HOST_IA32_PAT));
+       vmwrite(GUEST_IA32_EFER, vmreadz(HOST_IA32_EFER));
+       vmwrite(GUEST_IA32_PERF_GLOBAL_CTRL,
+               vmreadz(HOST_IA32_PERF_GLOBAL_CTRL));
+
+       vmwrite(GUEST_ES_LIMIT, -1);
+       vmwrite(GUEST_CS_LIMIT, -1);
+       vmwrite(GUEST_SS_LIMIT, -1);
+       vmwrite(GUEST_DS_LIMIT, -1);
+       vmwrite(GUEST_FS_LIMIT, -1);
+       vmwrite(GUEST_GS_LIMIT, -1);
+       vmwrite(GUEST_LDTR_LIMIT, -1);
+       vmwrite(GUEST_TR_LIMIT, 0x67);
+       vmwrite(GUEST_GDTR_LIMIT, 0xffff);
+       vmwrite(GUEST_IDTR_LIMIT, 0xffff);
+       vmwrite(GUEST_ES_AR_BYTES,
+               vmreadz(GUEST_ES_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_CS_AR_BYTES, 0xa09b);
+       vmwrite(GUEST_SS_AR_BYTES, 0xc093);
+       vmwrite(GUEST_DS_AR_BYTES,
+               vmreadz(GUEST_DS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_FS_AR_BYTES,
+               vmreadz(GUEST_FS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_GS_AR_BYTES,
+               vmreadz(GUEST_GS_SELECTOR) == 0 ? 0x10000 : 0xc093);
+       vmwrite(GUEST_LDTR_AR_BYTES, 0x10000);
+       vmwrite(GUEST_TR_AR_BYTES, 0x8b);
+       vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
+       vmwrite(GUEST_ACTIVITY_STATE, 0);
+       vmwrite(GUEST_SYSENTER_CS, vmreadz(HOST_IA32_SYSENTER_CS));
+       vmwrite(VMX_PREEMPTION_TIMER_VALUE, 0);
+
+       vmwrite(GUEST_CR0, vmreadz(HOST_CR0));
+       vmwrite(GUEST_CR3, vmreadz(HOST_CR3));
+       vmwrite(GUEST_CR4, vmreadz(HOST_CR4));
+       vmwrite(GUEST_ES_BASE, 0);
+       vmwrite(GUEST_CS_BASE, 0);
+       vmwrite(GUEST_SS_BASE, 0);
+       vmwrite(GUEST_DS_BASE, 0);
+       vmwrite(GUEST_FS_BASE, vmreadz(HOST_FS_BASE));
+       vmwrite(GUEST_GS_BASE, vmreadz(HOST_GS_BASE));
+       vmwrite(GUEST_LDTR_BASE, 0);
+       vmwrite(GUEST_TR_BASE, vmreadz(HOST_TR_BASE));
+       vmwrite(GUEST_GDTR_BASE, vmreadz(HOST_GDTR_BASE));
+       vmwrite(GUEST_IDTR_BASE, vmreadz(HOST_IDTR_BASE));
+       vmwrite(GUEST_DR7, 0x400);
+       vmwrite(GUEST_RSP, (uint64_t)rsp);
+       vmwrite(GUEST_RIP, (uint64_t)rip);
+       vmwrite(GUEST_RFLAGS, 2);
+       vmwrite(GUEST_PENDING_DBG_EXCEPTIONS, 0);
+       vmwrite(GUEST_SYSENTER_ESP, vmreadz(HOST_IA32_SYSENTER_ESP));
+       vmwrite(GUEST_SYSENTER_EIP, vmreadz(HOST_IA32_SYSENTER_EIP));
+}
+
+void prepare_vmcs(void *guest_rip, void *guest_rsp)
+{
+       init_vmcs_control_fields();
+       init_vmcs_host_state();
+       init_vmcs_guest_state(guest_rip, guest_rsp);
+}
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
new file mode 100644 (file)
index 0000000..8f7f620
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * gtests/tests/vmx_tsc_adjust_test.c
+ *
+ * Copyright (C) 2018, Google LLC.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ *
+ * IA32_TSC_ADJUST test
+ *
+ * According to the SDM, "if an execution of WRMSR to the
+ * IA32_TIME_STAMP_COUNTER MSR adds (or subtracts) value X from the TSC,
+ * the logical processor also adds (or subtracts) value X from the
+ * IA32_TSC_ADJUST MSR.
+ *
+ * Note that when L1 doesn't intercept writes to IA32_TSC, a
+ * WRMSR(IA32_TSC) from L2 sets L1's TSC value, not L2's perceived TSC
+ * value.
+ *
+ * This test verifies that this unusual case is handled correctly.
+ */
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "x86.h"
+#include "vmx.h"
+
+#include <string.h>
+#include <sys/ioctl.h>
+
+#ifndef MSR_IA32_TSC_ADJUST
+#define MSR_IA32_TSC_ADJUST 0x3b
+#endif
+
+#define PAGE_SIZE      4096
+#define VCPU_ID                5
+
+#define TSC_ADJUST_VALUE (1ll << 32)
+#define TSC_OFFSET_VALUE -(1ll << 48)
+
+enum {
+       PORT_ABORT = 0x1000,
+       PORT_REPORT,
+       PORT_DONE,
+};
+
+struct vmx_page {
+       vm_vaddr_t virt;
+       vm_paddr_t phys;
+};
+
+enum {
+       VMXON_PAGE = 0,
+       VMCS_PAGE,
+       MSR_BITMAP_PAGE,
+
+       NUM_VMX_PAGES,
+};
+
+struct kvm_single_msr {
+       struct kvm_msrs header;
+       struct kvm_msr_entry entry;
+} __attribute__((packed));
+
+/* The virtual machine object. */
+static struct kvm_vm *vm;
+
+/* Array of vmx_page descriptors that is shared with the guest. */
+struct vmx_page *vmx_pages;
+
+#define exit_to_l0(_port, _arg) do_exit_to_l0(_port, (unsigned long) (_arg))
+static void do_exit_to_l0(uint16_t port, unsigned long arg)
+{
+       __asm__ __volatile__("in %[port], %%al"
+               :
+               : [port]"d"(port), "D"(arg)
+               : "rax");
+}
+
+
+#define GUEST_ASSERT(_condition) do {                                       \
+       if (!(_condition))                                                   \
+               exit_to_l0(PORT_ABORT, "Failed guest assert: " #_condition); \
+} while (0)
+
+static void check_ia32_tsc_adjust(int64_t max)
+{
+       int64_t adjust;
+
+       adjust = rdmsr(MSR_IA32_TSC_ADJUST);
+       exit_to_l0(PORT_REPORT, adjust);
+       GUEST_ASSERT(adjust <= max);
+}
+
+static void l2_guest_code(void)
+{
+       uint64_t l1_tsc = rdtsc() - TSC_OFFSET_VALUE;
+
+       wrmsr(MSR_IA32_TSC, l1_tsc - TSC_ADJUST_VALUE);
+       check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
+
+       /* Exit to L1 */
+       __asm__ __volatile__("vmcall");
+}
+
+static void l1_guest_code(struct vmx_page *vmx_pages)
+{
+#define L2_GUEST_STACK_SIZE 64
+       unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE];
+       uint32_t control;
+       uintptr_t save_cr3;
+
+       GUEST_ASSERT(rdtsc() < TSC_ADJUST_VALUE);
+       wrmsr(MSR_IA32_TSC, rdtsc() - TSC_ADJUST_VALUE);
+       check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
+
+       prepare_for_vmx_operation();
+
+       /* Enter VMX root operation. */
+       *(uint32_t *)vmx_pages[VMXON_PAGE].virt = vmcs_revision();
+       GUEST_ASSERT(!vmxon(vmx_pages[VMXON_PAGE].phys));
+
+       /* Load a VMCS. */
+       *(uint32_t *)vmx_pages[VMCS_PAGE].virt = vmcs_revision();
+       GUEST_ASSERT(!vmclear(vmx_pages[VMCS_PAGE].phys));
+       GUEST_ASSERT(!vmptrld(vmx_pages[VMCS_PAGE].phys));
+
+       /* Prepare the VMCS for L2 execution. */
+       prepare_vmcs(l2_guest_code, &l2_guest_stack[L2_GUEST_STACK_SIZE]);
+       control = vmreadz(CPU_BASED_VM_EXEC_CONTROL);
+       control |= CPU_BASED_USE_MSR_BITMAPS | CPU_BASED_USE_TSC_OFFSETING;
+       vmwrite(CPU_BASED_VM_EXEC_CONTROL, control);
+       vmwrite(MSR_BITMAP, vmx_pages[MSR_BITMAP_PAGE].phys);
+       vmwrite(TSC_OFFSET, TSC_OFFSET_VALUE);
+
+       /* Jump into L2.  First, test failure to load guest CR3.  */
+       save_cr3 = vmreadz(GUEST_CR3);
+       vmwrite(GUEST_CR3, -1ull);
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) ==
+                    (EXIT_REASON_FAILED_VMENTRY | EXIT_REASON_INVALID_STATE));
+       check_ia32_tsc_adjust(-1 * TSC_ADJUST_VALUE);
+       vmwrite(GUEST_CR3, save_cr3);
+
+       GUEST_ASSERT(!vmlaunch());
+       GUEST_ASSERT(vmreadz(VM_EXIT_REASON) == EXIT_REASON_VMCALL);
+
+       check_ia32_tsc_adjust(-2 * TSC_ADJUST_VALUE);
+
+       exit_to_l0(PORT_DONE, 0);
+}
+
+static void allocate_vmx_page(struct vmx_page *page)
+{
+       vm_vaddr_t virt;
+
+       virt = vm_vaddr_alloc(vm, PAGE_SIZE, 0, 0, 0);
+       memset(addr_gva2hva(vm, virt), 0, PAGE_SIZE);
+
+       page->virt = virt;
+       page->phys = addr_gva2gpa(vm, virt);
+}
+
+static vm_vaddr_t allocate_vmx_pages(void)
+{
+       vm_vaddr_t vmx_pages_vaddr;
+       int i;
+
+       vmx_pages_vaddr = vm_vaddr_alloc(
+               vm, sizeof(struct vmx_page) * NUM_VMX_PAGES, 0, 0, 0);
+
+       vmx_pages = (void *) addr_gva2hva(vm, vmx_pages_vaddr);
+
+       for (i = 0; i < NUM_VMX_PAGES; i++)
+               allocate_vmx_page(&vmx_pages[i]);
+
+       return vmx_pages_vaddr;
+}
+
+void report(int64_t val)
+{
+       printf("IA32_TSC_ADJUST is %ld (%lld * TSC_ADJUST_VALUE + %lld).\n",
+              val, val / TSC_ADJUST_VALUE, val % TSC_ADJUST_VALUE);
+}
+
+int main(int argc, char *argv[])
+{
+       vm_vaddr_t vmx_pages_vaddr;
+       struct kvm_cpuid_entry2 *entry = kvm_get_supported_cpuid_entry(1);
+
+       if (!(entry->ecx & CPUID_VMX)) {
+               printf("nested VMX not enabled, skipping test");
+               return 0;
+       }
+
+       vm = vm_create_default_vmx(VCPU_ID, (void *) l1_guest_code);
+
+       /* Allocate VMX pages and shared descriptors (vmx_pages). */
+       vmx_pages_vaddr = allocate_vmx_pages();
+       vcpu_args_set(vm, VCPU_ID, 1, vmx_pages_vaddr);
+
+       for (;;) {
+               volatile struct kvm_run *run = vcpu_state(vm, VCPU_ID);
+               struct kvm_regs regs;
+
+               vcpu_run(vm, VCPU_ID);
+               TEST_ASSERT(run->exit_reason == KVM_EXIT_IO,
+                           "Got exit_reason other than KVM_EXIT_IO: %u (%s),\n",
+                           run->exit_reason,
+                           exit_reason_str(run->exit_reason));
+
+               vcpu_regs_get(vm, VCPU_ID, &regs);
+
+               switch (run->io.port) {
+               case PORT_ABORT:
+                       TEST_ASSERT(false, "%s", (const char *) regs.rdi);
+                       /* NOT REACHED */
+               case PORT_REPORT:
+                       report(regs.rdi);
+                       break;
+               case PORT_DONE:
+                       goto done;
+               default:
+                       TEST_ASSERT(false, "Unknown port 0x%x.", run->io.port);
+               }
+       }
+
+       kvm_vm_free(vm);
+done:
+       return 0;
+}
index 785fc18..8f1e13d 100644 (file)
@@ -5,7 +5,7 @@ CFLAGS =  -Wall -Wl,--no-as-needed -O2 -g
 CFLAGS += -I../../../../usr/include/
 
 TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh rtnetlink.sh
-TEST_PROGS += fib_tests.sh fib-onlink-tests.sh pmtu.sh
+TEST_PROGS += fib_tests.sh fib-onlink-tests.sh in_netns.sh pmtu.sh
 TEST_GEN_FILES =  socket
 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy
 TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa