Merge tag '5.11-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jan 2021 17:27:14 +0000 (09:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 24 Jan 2021 17:27:14 +0000 (09:27 -0800)
Pull cifs fixes from Steve French:
 "An important signal handling patch for stable, and two small cleanup
  patches"

* tag '5.11-rc4-smb3' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: do not fail __smb_send_rqst if non-fatal signals are pending
  fs/cifs: Simplify bool comparison.
  fs/cifs: Assign boolean values to a bool variable

192 files changed:
.mailmap
Documentation/ABI/testing/sysfs-driver-ufs
Documentation/admin-guide/device-mapper/dm-integrity.rst
Documentation/dev-tools/kunit/usage.rst
Documentation/networking/tls-offload.rst
MAINTAINERS
arch/arm64/kernel/probes/kprobes.c
arch/arm64/mm/fault.c
arch/ia64/include/asm/sparsemem.h
arch/openrisc/include/asm/io.h
arch/openrisc/mm/ioremap.c
arch/x86/hyperv/hv_init.c
arch/x86/xen/smp_hvm.c
crypto/asymmetric_keys/public_key.c
crypto/xor.c
drivers/acpi/scan.c
drivers/crypto/Kconfig
drivers/gpio/Kconfig
drivers/gpio/gpio-mvebu.c
drivers/gpio/gpiolib-cdev.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v2_3.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c
drivers/gpu/drm/drm_atomic_helper.c
drivers/gpu/drm/drm_gem_vram_helper.c
drivers/gpu/drm/drm_syncobj.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp.h
drivers/gpu/drm/i915/display/intel_hdcp.c
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
drivers/gpu/drm/i915/gt/intel_lrc.c
drivers/gpu/drm/i915/gt/intel_timeline.c
drivers/gpu/drm/i915/i915_pmu.c
drivers/gpu/drm/i915/i915_request.h
drivers/gpu/drm/ttm/ttm_pool.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-octeon-core.c
drivers/i2c/busses/i2c-tegra-bpmp.c
drivers/i2c/busses/i2c-tegra.c
drivers/md/dm-crypt.c
drivers/md/dm-integrity.c
drivers/md/dm-table.c
drivers/mmc/core/queue.c
drivers/mmc/host/sdhci-brcmstb.c
drivers/mmc/host/sdhci-of-dwcmshc.c
drivers/mmc/host/sdhci-xenon.c
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/raw/intel-nand-controller.c
drivers/mtd/nand/raw/nandsim.c
drivers/mtd/nand/raw/omap2.c
drivers/mtd/nand/spi/core.c
drivers/net/can/dev.c
drivers/net/can/usb/peak_usb/pcan_usb_fd.c
drivers/net/can/vxcan.c
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/mv88e6xxx/global1_vtu.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
drivers/net/ethernet/mscc/ocelot.c
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/mdio/mdio-bitbang.c
drivers/net/usb/cdc_ncm.c
drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
drivers/pinctrl/nomadik/pinctrl-nomadik.c
drivers/pinctrl/pinctrl-ingenic.c
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/qcom/pinctrl-msm.h
drivers/platform/surface/Kconfig
drivers/platform/surface/surface_gpe.c
drivers/platform/x86/amd-pmc.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/i2c-multi-instantiate.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/intel-vbtn.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/touchscreen_dmi.c
drivers/scsi/fnic/vnic_dev.c
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/libfc/fc_exch.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/scsi_transport_srp.c
drivers/scsi/ufs/Kconfig
drivers/scsi/ufs/ufshcd.c
drivers/soc/litex/litex_soc_ctrl.c
drivers/spi/spi-cadence.c
drivers/spi/spi-fsl-spi.c
drivers/target/target_core_user.c
fs/btrfs/backref.c
fs/btrfs/block-group.c
fs/btrfs/extent-tree.c
fs/btrfs/send.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/cachefiles/rdwr.c
fs/ceph/mds_client.c
fs/fs-writeback.c
fs/nfsd/nfs3xdr.c
fs/udf/super.c
include/linux/mdio-bitbang.h
include/linux/usb/usbnet.h
include/net/cfg80211.h
include/net/inet_connection_sock.h
include/net/mac80211.h
include/net/sock.h
include/trace/events/sunrpc.h
kernel/bpf/bpf_inode_storage.c
kernel/bpf/bpf_task_storage.c
kernel/bpf/btf.c
kernel/bpf/cgroup.c
kernel/bpf/helpers.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/printk/printk.c
kernel/printk/printk_ringbuffer.c
kernel/signal.c
mm/memblock.c
net/bpf/test_run.c
net/ceph/auth_x.c
net/ceph/crypto.c
net/ceph/messenger_v1.c
net/ceph/messenger_v2.c
net/ceph/mon_client.c
net/ceph/osd_client.c
net/core/dev.c
net/core/devlink.c
net/core/gen_estimator.c
net/core/skbuff.c
net/ipv4/inet_connection_sock.c
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/tcp_timer.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/mac80211/debugfs.c
net/mac80211/rx.c
net/mac80211/tx.c
net/nfc/nci/core.c
net/sched/cls_flower.c
net/sched/cls_tcindex.c
net/sched/sch_api.c
net/sunrpc/svc_xprt.c
net/wireless/reg.c
net/xdp/xsk.c
sound/core/seq/oss/seq_oss_synth.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/soc/codecs/hdmi-codec.c
sound/soc/fsl/imx-hdmi.c
sound/soc/sof/intel/hda-codec.c
sound/soc/sof/intel/hda-dsp.c
sound/soc/sof/intel/hda.h
sound/usb/clock.c
sound/usb/endpoint.c
sound/usb/implicit.c
sound/usb/pcm.c
sound/usb/quirks.c
tools/gpio/gpio-event-mon.c
tools/gpio/gpio-watch.c
tools/lib/bpf/btf.c
tools/lib/perf/evlist.c
tools/perf/builtin-script.c
tools/perf/util/metricgroup.c
tools/power/x86/intel-speed-select/isst-config.c
tools/testing/kunit/kunit.py
tools/testing/kunit/kunit_config.py
tools/testing/kunit/kunit_json.py
tools/testing/kunit/kunit_kernel.py
tools/testing/kunit/kunit_parser.py
tools/testing/selftests/bpf/prog_tests/test_local_storage.c
tools/testing/selftests/bpf/progs/local_storage.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/bpf/verifier/spill_fill.c
tools/testing/selftests/net/fib_tests.sh

index 632700c..b1ab012 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -55,6 +55,8 @@ Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
 Ben Gardner <bgardner@wabtec.com>
 Ben M Cahill <ben.m.cahill@intel.com>
 Björn Steinbrink <B.Steinbrink@gmx.de>
+Björn Töpel <bjorn@kernel.org> <bjorn.topel@gmail.com>
+Björn Töpel <bjorn@kernel.org> <bjorn.topel@intel.com>
 Boris Brezillon <bbrezillon@kernel.org> <b.brezillon.dev@gmail.com>
 Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com>
 Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
index adc0d0e..75ccc5c 100644 (file)
@@ -916,21 +916,25 @@ Date:             September 2014
 Contact:       Subhash Jadavani <subhashj@codeaurora.org>
 Description:   This entry could be used to set or show the UFS device
                runtime power management level. The current driver
-               implementation supports 6 levels with next target states:
+               implementation supports 7 levels with next target states:
 
                ==  ====================================================
-               0   an UFS device will stay active, an UIC link will
+               0   UFS device will stay active, UIC link will
                    stay active
-               1   an UFS device will stay active, an UIC link will
+               1   UFS device will stay active, UIC link will
                    hibernate
-               2   an UFS device will moved to sleep, an UIC link will
+               2   UFS device will be moved to sleep, UIC link will
                    stay active
-               3   an UFS device will moved to sleep, an UIC link will
+               3   UFS device will be moved to sleep, UIC link will
                    hibernate
-               4   an UFS device will be powered off, an UIC link will
+               4   UFS device will be powered off, UIC link will
                    hibernate
-               5   an UFS device will be powered off, an UIC link will
+               5   UFS device will be powered off, UIC link will
                    be powered off
+               6   UFS device will be moved to deep sleep, UIC link
+                   will be powered off. Note, deep sleep might not be
+                   supported in which case this value will not be
+                   accepted
                ==  ====================================================
 
 What:          /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state
@@ -954,21 +958,25 @@ Date:             September 2014
 Contact:       Subhash Jadavani <subhashj@codeaurora.org>
 Description:   This entry could be used to set or show the UFS device
                system power management level. The current driver
-               implementation supports 6 levels with next target states:
+               implementation supports 7 levels with next target states:
 
                ==  ====================================================
-               0   an UFS device will stay active, an UIC link will
+               0   UFS device will stay active, UIC link will
                    stay active
-               1   an UFS device will stay active, an UIC link will
+               1   UFS device will stay active, UIC link will
                    hibernate
-               2   an UFS device will moved to sleep, an UIC link will
+               2   UFS device will be moved to sleep, UIC link will
                    stay active
-               3   an UFS device will moved to sleep, an UIC link will
+               3   UFS device will be moved to sleep, UIC link will
                    hibernate
-               4   an UFS device will be powered off, an UIC link will
+               4   UFS device will be powered off, UIC link will
                    hibernate
-               5   an UFS device will be powered off, an UIC link will
+               5   UFS device will be powered off, UIC link will
                    be powered off
+               6   UFS device will be moved to deep sleep, UIC link
+                   will be powered off. Note, deep sleep might not be
+                   supported in which case this value will not be
+                   accepted
                ==  ====================================================
 
 What:          /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state
index 4e6f504..2cc5488 100644 (file)
@@ -177,14 +177,20 @@ bitmap_flush_interval:number
        The bitmap flush interval in milliseconds. The metadata buffers
        are synchronized when this interval expires.
 
+allow_discards
+       Allow block discard requests (a.k.a. TRIM) for the integrity device.
+       Discards are only allowed to devices using internal hash.
+
 fix_padding
        Use a smaller padding of the tag area that is more
        space-efficient. If this option is not present, large padding is
        used - that is for compatibility with older kernels.
 
-allow_discards
-       Allow block discard requests (a.k.a. TRIM) for the integrity device.
-       Discards are only allowed to devices using internal hash.
+legacy_recalculate
+       Allow recalculating of volumes with HMAC keys. This is disabled by
+       default for security reasons - an attacker could modify the volume,
+       set recalc_sector to zero, and the kernel would not detect the
+       modification.
 
 The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and
 allow_discards can be changed when reloading the target (load an inactive
index d9fdc14..650f995 100644 (file)
@@ -522,6 +522,63 @@ There's more boilerplate involved, but it can:
   * E.g. if we wanted to also test ``sha256sum``, we could add a ``sha256``
     field and reuse ``cases``.
 
+* be converted to a "parameterized test", see below.
+
+Parameterized Testing
+~~~~~~~~~~~~~~~~~~~~~
+
+The table-driven testing pattern is common enough that KUnit has special
+support for it.
+
+Reusing the same ``cases`` array from above, we can write the test as a
+"parameterized test" with the following.
+
+.. code-block:: c
+
+       // This is copy-pasted from above.
+       struct sha1_test_case {
+               const char *str;
+               const char *sha1;
+       };
+       struct sha1_test_case cases[] = {
+               {
+                       .str = "hello world",
+                       .sha1 = "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed",
+               },
+               {
+                       .str = "hello world!",
+                       .sha1 = "430ce34d020724ed75a196dfc2ad67c77772d169",
+               },
+       };
+
+       // Need a helper function to generate a name for each test case.
+       static void case_to_desc(const struct sha1_test_case *t, char *desc)
+       {
+               strcpy(desc, t->str);
+       }
+       // Creates `sha1_gen_params()` to iterate over `cases`.
+       KUNIT_ARRAY_PARAM(sha1, cases, case_to_desc);
+
+       // Looks no different from a normal test.
+       static void sha1_test(struct kunit *test)
+       {
+               // This function can just contain the body of the for-loop.
+               // The former `cases[i]` is accessible under test->param_value.
+               char out[40];
+               struct sha1_test_case *test_param = (struct sha1_test_case *)(test->param_value);
+
+               sha1sum(test_param->str, out);
+               KUNIT_EXPECT_STREQ_MSG(test, (char *)out, test_param->sha1,
+                                     "sha1sum(%s)", test_param->str);
+       }
+
+       // Instead of KUNIT_CASE, we use KUNIT_CASE_PARAM and pass in the
+       // function declared by KUNIT_ARRAY_PARAM.
+       static struct kunit_case sha1_test_cases[] = {
+               KUNIT_CASE_PARAM(sha1_test, sha1_gen_params),
+               {}
+       };
+
 .. _kunit-on-non-uml:
 
 KUnit on non-UML architectures
index 9af3334..5f0dea3 100644 (file)
@@ -534,3 +534,6 @@ offload. Hence, TLS TX device feature flag requires TX csum offload being set.
 Disabling the latter implies clearing the former. Disabling TX checksum offload
 should not affect old connections, and drivers should make sure checksum
 calculation does not break for them.
+Similarly, device-offloaded TLS decryption implies doing RXCSUM. If the user
+does not want to enable RX csum offload, TLS RX device feature is disabled
+as well.
index 00836f6..f79ec98 100644 (file)
@@ -3334,7 +3334,7 @@ F:        arch/riscv/net/
 X:     arch/riscv/net/bpf_jit_comp64.c
 
 BPF JIT for RISC-V (64-bit)
-M:     Björn Töpel <bjorn.topel@gmail.com>
+M:     Björn Töpel <bjorn@kernel.org>
 L:     netdev@vger.kernel.org
 L:     bpf@vger.kernel.org
 S:     Maintained
@@ -14504,10 +14504,18 @@ S:    Supported
 F:     drivers/crypto/qat/
 
 QCOM AUDIO (ASoC) DRIVERS
-M:     Patrick Lai <plai@codeaurora.org>
+M:     Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 M:     Banajit Goswami <bgoswami@codeaurora.org>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Supported
+F:     sound/soc/codecs/lpass-va-macro.c
+F:     sound/soc/codecs/lpass-wsa-macro.*
+F:     sound/soc/codecs/msm8916-wcd-analog.c
+F:     sound/soc/codecs/msm8916-wcd-digital.c
+F:     sound/soc/codecs/wcd9335.*
+F:     sound/soc/codecs/wcd934x.c
+F:     sound/soc/codecs/wcd-clsh-v2.*
+F:     sound/soc/codecs/wsa881x.c
 F:     sound/soc/qcom/
 
 QCOM IPA DRIVER
@@ -16959,7 +16967,7 @@ M:      Olivier Moysan <olivier.moysan@st.com>
 M:     Arnaud Pouliquen <arnaud.pouliquen@st.com>
 L:     alsa-devel@alsa-project.org (moderated for non-subscribers)
 S:     Maintained
-F:     Documentation/devicetree/bindings/sound/st,stm32-*.txt
+F:     Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml
 F:     sound/soc/stm/
 
 STM32 TIMER/LPTIMER DRIVERS
@@ -19416,7 +19424,7 @@ F:      drivers/net/ethernet/*/*/*xdp*
 K:     (?:\b|_)xdp(?:\b|_)
 
 XDP SOCKETS (AF_XDP)
-M:     Björn Töpel <bjorn.topel@intel.com>
+M:     Björn Töpel <bjorn@kernel.org>
 M:     Magnus Karlsson <magnus.karlsson@intel.com>
 R:     Jonathan Lemon <jonathan.lemon@gmail.com>
 L:     netdev@vger.kernel.org
index 89c64ad..66aac28 100644 (file)
@@ -352,8 +352,8 @@ kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr)
        unsigned long addr = instruction_pointer(regs);
        struct kprobe *cur = kprobe_running();
 
-       if (cur && (kcb->kprobe_status == KPROBE_HIT_SS)
-           && ((unsigned long)&cur->ainsn.api.insn[1] == addr)) {
+       if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
+           ((unsigned long)&cur->ainsn.api.insn[1] == addr)) {
                kprobes_restore_local_irqflag(kcb, regs);
                post_kprobe_handler(cur, kcb, regs);
 
index 3c40da4..35d75c6 100644 (file)
@@ -709,10 +709,11 @@ static int do_tag_check_fault(unsigned long far, unsigned int esr,
                              struct pt_regs *regs)
 {
        /*
-        * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN for tag
-        * check faults. Mask them out now so that userspace doesn't see them.
+        * The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
+        * for tag check faults. Set them to corresponding bits in the untagged
+        * address.
         */
-       far &= (1UL << 60) - 1;
+       far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
        do_bad_area(far, esr, regs);
        return 0;
 }
index dd8c166..42ed524 100644 (file)
@@ -3,6 +3,7 @@
 #define _ASM_IA64_SPARSEMEM_H
 
 #ifdef CONFIG_SPARSEMEM
+#include <asm/page.h>
 /*
  * SECTION_SIZE_BITS            2^N: how big each section will be
  * MAX_PHYSMEM_BITS             2^N: how much memory we can have in that space
index 7d6b4a7..c298061 100644 (file)
@@ -31,7 +31,7 @@
 void __iomem *ioremap(phys_addr_t offset, unsigned long size);
 
 #define iounmap iounmap
-extern void iounmap(void *addr);
+extern void iounmap(void __iomem *addr);
 
 #include <asm-generic/io.h>
 
index 5aed97a..daae13a 100644 (file)
@@ -77,7 +77,7 @@ void __iomem *__ref ioremap(phys_addr_t addr, unsigned long size)
 }
 EXPORT_SYMBOL(ioremap);
 
-void iounmap(void *addr)
+void iounmap(void __iomem *addr)
 {
        /* If the page is from the fixmap pool then we just clear out
         * the fixmap mapping.
index 4638a52..6375967 100644 (file)
@@ -315,6 +315,25 @@ static struct syscore_ops hv_syscore_ops = {
        .resume         = hv_resume,
 };
 
+static void (* __initdata old_setup_percpu_clockev)(void);
+
+static void __init hv_stimer_setup_percpu_clockev(void)
+{
+       /*
+        * Ignore any errors in setting up stimer clockevents
+        * as we can run with the LAPIC timer as a fallback.
+        */
+       (void)hv_stimer_alloc();
+
+       /*
+        * Still register the LAPIC timer, because the direct-mode STIMER is
+        * not supported by old versions of Hyper-V. This also allows users
+        * to switch to LAPIC timer via /sys, if they want to.
+        */
+       if (old_setup_percpu_clockev)
+               old_setup_percpu_clockev();
+}
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
@@ -393,10 +412,14 @@ void __init hyperv_init(void)
        wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
        /*
-        * Ignore any errors in setting up stimer clockevents
-        * as we can run with the LAPIC timer as a fallback.
+        * hyperv_init() is called before LAPIC is initialized: see
+        * apic_intr_mode_init() -> x86_platform.apic_post_init() and
+        * apic_bsp_setup() -> setup_local_APIC(). The direct-mode STIMER
+        * depends on LAPIC, so hv_stimer_alloc() should be called from
+        * x86_init.timers.setup_percpu_clockev.
         */
-       (void)hv_stimer_alloc();
+       old_setup_percpu_clockev = x86_init.timers.setup_percpu_clockev;
+       x86_init.timers.setup_percpu_clockev = hv_stimer_setup_percpu_clockev;
 
        hv_apic_init();
 
index 056430a..6ff3c88 100644 (file)
@@ -74,7 +74,9 @@ void __init xen_hvm_smp_init(void)
        smp_ops.cpu_die = xen_hvm_cpu_die;
 
        if (!xen_have_vector_callback) {
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
                nopvspin = true;
+#endif
                return;
        }
 
index 8892908..788a4ba 100644 (file)
@@ -356,7 +356,8 @@ int public_key_verify_signature(const struct public_key *pkey,
        if (ret)
                goto error_free_key;
 
-       if (strcmp(sig->pkey_algo, "sm2") == 0 && sig->data_size) {
+       if (sig->pkey_algo && strcmp(sig->pkey_algo, "sm2") == 0 &&
+           sig->data_size) {
                ret = cert_sig_digest_update(sig, tfm);
                if (ret)
                        goto error_free_key;
index eacbf4f..8f899f8 100644 (file)
@@ -107,6 +107,8 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
        preempt_enable();
 
        // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
+       if (!min)
+               min = 1;
        speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
        tmpl->speed = speed;
 
index 58ff363..1db063b 100644 (file)
@@ -586,6 +586,8 @@ static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device,
        if (!device)
                return -EINVAL;
 
+       *device = NULL;
+
        status = acpi_get_data_full(handle, acpi_scan_drop_device,
                                    (void **)device, callback);
        if (ACPI_FAILURE(status) || !*device) {
index bbd5170..e535f28 100644 (file)
@@ -366,6 +366,7 @@ if CRYPTO_DEV_OMAP
 config CRYPTO_DEV_OMAP_SHAM
        tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator"
        depends on ARCH_OMAP2PLUS
+       select CRYPTO_ENGINE
        select CRYPTO_SHA1
        select CRYPTO_MD5
        select CRYPTO_SHA256
index c70f46e..dea65d8 100644 (file)
@@ -521,7 +521,8 @@ config GPIO_SAMA5D2_PIOBU
 
 config GPIO_SIFIVE
        bool "SiFive GPIO support"
-       depends on OF_GPIO && IRQ_DOMAIN_HIERARCHY
+       depends on OF_GPIO
+       select IRQ_DOMAIN_HIERARCHY
        select GPIO_GENERIC
        select GPIOLIB_IRQCHIP
        select REGMAP_MMIO
@@ -597,6 +598,8 @@ config GPIO_TEGRA
        default ARCH_TEGRA
        depends on ARCH_TEGRA || COMPILE_TEST
        depends on OF_GPIO
+       select GPIOLIB_IRQCHIP
+       select IRQ_DOMAIN_HIERARCHY
        help
          Say yes here to support GPIO pins on NVIDIA Tegra SoCs.
 
index 672681a..a912a8f 100644 (file)
@@ -676,20 +676,17 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
        else
                state->duty_cycle = 1;
 
+       val = (unsigned long long) u; /* on duration */
        regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
-       val = (unsigned long long) u * NSEC_PER_SEC;
+       val += (unsigned long long) u; /* period = on + off duration */
+       val *= NSEC_PER_SEC;
        do_div(val, mvpwm->clk_rate);
-       if (val < state->duty_cycle) {
+       if (val > UINT_MAX)
+               state->period = UINT_MAX;
+       else if (val)
+               state->period = val;
+       else
                state->period = 1;
-       } else {
-               val -= state->duty_cycle;
-               if (val > UINT_MAX)
-                       state->period = UINT_MAX;
-               else if (val)
-                       state->period = val;
-               else
-                       state->period = 1;
-       }
 
        regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u);
        if (u)
index 12b679c..1a7b511 100644 (file)
@@ -1979,6 +1979,21 @@ struct gpio_chardev_data {
 #endif
 };
 
+static int chipinfo_get(struct gpio_chardev_data *cdev, void __user *ip)
+{
+       struct gpio_device *gdev = cdev->gdev;
+       struct gpiochip_info chipinfo;
+
+       memset(&chipinfo, 0, sizeof(chipinfo));
+
+       strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name));
+       strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label));
+       chipinfo.lines = gdev->ngpio;
+       if (copy_to_user(ip, &chipinfo, sizeof(chipinfo)))
+               return -EFAULT;
+       return 0;
+}
+
 #ifdef CONFIG_GPIO_CDEV_V1
 /*
  * returns 0 if the versions match, else the previously selected ABI version
@@ -1993,6 +2008,41 @@ static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata,
 
        return abiv;
 }
+
+static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip,
+                          bool watch)
+{
+       struct gpio_desc *desc;
+       struct gpioline_info lineinfo;
+       struct gpio_v2_line_info lineinfo_v2;
+
+       if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
+               return -EFAULT;
+
+       /* this doubles as a range check on line_offset */
+       desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.line_offset);
+       if (IS_ERR(desc))
+               return PTR_ERR(desc);
+
+       if (watch) {
+               if (lineinfo_ensure_abi_version(cdev, 1))
+                       return -EPERM;
+
+               if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines))
+                       return -EBUSY;
+       }
+
+       gpio_desc_to_lineinfo(desc, &lineinfo_v2);
+       gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
+
+       if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
+               if (watch)
+                       clear_bit(lineinfo.line_offset, cdev->watched_lines);
+               return -EFAULT;
+       }
+
+       return 0;
+}
 #endif
 
 static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
@@ -2030,6 +2080,22 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
        return 0;
 }
 
+static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
+{
+       __u32 offset;
+
+       if (copy_from_user(&offset, ip, sizeof(offset)))
+               return -EFAULT;
+
+       if (offset >= cdev->gdev->ngpio)
+               return -EINVAL;
+
+       if (!test_and_clear_bit(offset, cdev->watched_lines))
+               return -EBUSY;
+
+       return 0;
+}
+
 /*
  * gpio_ioctl() - ioctl handler for the GPIO chardev
  */
@@ -2037,80 +2103,24 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        struct gpio_chardev_data *cdev = file->private_data;
        struct gpio_device *gdev = cdev->gdev;
-       struct gpio_chip *gc = gdev->chip;
        void __user *ip = (void __user *)arg;
-       __u32 offset;
 
        /* We fail any subsequent ioctl():s when the chip is gone */
-       if (!gc)
+       if (!gdev->chip)
                return -ENODEV;
 
        /* Fill in the struct and pass to userspace */
        if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
-               struct gpiochip_info chipinfo;
-
-               memset(&chipinfo, 0, sizeof(chipinfo));
-
-               strscpy(chipinfo.name, dev_name(&gdev->dev),
-                       sizeof(chipinfo.name));
-               strscpy(chipinfo.label, gdev->label,
-                       sizeof(chipinfo.label));
-               chipinfo.lines = gdev->ngpio;
-               if (copy_to_user(ip, &chipinfo, sizeof(chipinfo)))
-                       return -EFAULT;
-               return 0;
+               return chipinfo_get(cdev, ip);
 #ifdef CONFIG_GPIO_CDEV_V1
-       } else if (cmd == GPIO_GET_LINEINFO_IOCTL) {
-               struct gpio_desc *desc;
-               struct gpioline_info lineinfo;
-               struct gpio_v2_line_info lineinfo_v2;
-
-               if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
-                       return -EFAULT;
-
-               /* this doubles as a range check on line_offset */
-               desc = gpiochip_get_desc(gc, lineinfo.line_offset);
-               if (IS_ERR(desc))
-                       return PTR_ERR(desc);
-
-               gpio_desc_to_lineinfo(desc, &lineinfo_v2);
-               gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
-
-               if (copy_to_user(ip, &lineinfo, sizeof(lineinfo)))
-                       return -EFAULT;
-               return 0;
        } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
                return linehandle_create(gdev, ip);
        } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
                return lineevent_create(gdev, ip);
-       } else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
-               struct gpio_desc *desc;
-               struct gpioline_info lineinfo;
-               struct gpio_v2_line_info lineinfo_v2;
-
-               if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
-                       return -EFAULT;
-
-               /* this doubles as a range check on line_offset */
-               desc = gpiochip_get_desc(gc, lineinfo.line_offset);
-               if (IS_ERR(desc))
-                       return PTR_ERR(desc);
-
-               if (lineinfo_ensure_abi_version(cdev, 1))
-                       return -EPERM;
-
-               if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines))
-                       return -EBUSY;
-
-               gpio_desc_to_lineinfo(desc, &lineinfo_v2);
-               gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
-
-               if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
-                       clear_bit(lineinfo.line_offset, cdev->watched_lines);
-                       return -EFAULT;
-               }
-
-               return 0;
+       } else if (cmd == GPIO_GET_LINEINFO_IOCTL ||
+                  cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
+               return lineinfo_get_v1(cdev, ip,
+                                      cmd == GPIO_GET_LINEINFO_WATCH_IOCTL);
 #endif /* CONFIG_GPIO_CDEV_V1 */
        } else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL ||
                   cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) {
@@ -2119,16 +2129,7 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        } else if (cmd == GPIO_V2_GET_LINE_IOCTL) {
                return linereq_create(gdev, ip);
        } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
-               if (copy_from_user(&offset, ip, sizeof(offset)))
-                       return -EFAULT;
-
-               if (offset >= cdev->gdev->ngpio)
-                       return -EINVAL;
-
-               if (!test_and_clear_bit(offset, cdev->watched_lines))
-                       return -EBUSY;
-
-               return 0;
+               return lineinfo_unwatch(cdev, ip);
        }
        return -EINVAL;
 }
index b02cc2a..b78a634 100644 (file)
@@ -1489,6 +1489,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
                type = IRQ_TYPE_NONE;
        }
 
+       if (gc->to_irq)
+               chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__);
+
        gc->to_irq = gpiochip_to_irq;
        gc->irq.default_type = type;
        gc->irq.lock_key = lock_key;
index 087afab..cab1eba 100644 (file)
@@ -81,7 +81,6 @@ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
 MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin");
-MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin");
 
 #define AMDGPU_RESUME_MS               2000
 
index 619d34c..346963e 100644 (file)
 #define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX    1
 #define mmSPI_CONFIG_CNTL_Vangogh                0x2440
 #define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX       1
+#define mmGCR_GENERAL_CNTL_Vangogh               0x1580
+#define mmGCR_GENERAL_CNTL_Vangogh_BASE_IDX      0
 
 #define mmCP_HYP_PFP_UCODE_ADDR                        0x5814
 #define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX       1
@@ -3244,7 +3246,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] =
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142),
-       SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
+       SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Vangogh, 0x1ff1ffff, 0x00000500),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210),
        SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210),
index 07104a1..1961745 100644 (file)
@@ -491,12 +491,11 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
 {
        uint32_t def, data, def1, data1;
 
-       def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
+       def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
        def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
 
        if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) {
-               data |= MM_ATC_L2_MISC_CG__ENABLE_MASK;
-
+               data &= ~MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK;
                data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
                           DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
                           DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
@@ -505,8 +504,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
                           DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
 
        } else {
-               data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK;
-
+               data |= MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK;
                data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
                          DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
                          DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
@@ -516,7 +514,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
        }
 
        if (def != data)
-               WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+               WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data);
        if (def1 != data1)
                WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1);
 }
@@ -525,17 +523,44 @@ static void
 mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev,
                                           bool enable)
 {
-       uint32_t def, data;
-
-       def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
-
-       if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS))
-               data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
-       else
-               data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
+       uint32_t def, data, def1, data1, def2, data2;
+
+       def  = data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
+       def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL);
+       def2 = data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL);
+
+       if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) {
+               data &= ~MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK;
+               data1 &= !(DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
+               data2 &= !(DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
+       } else {
+               data |= MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK;
+               data1 |= (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                       DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
+               data2 |= (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                       DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
+       }
 
        if (def != data)
-               WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
+               WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data);
+       if (def1 != data1)
+               WREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL, data1);
+       if (def2 != data2)
+               WREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL, data2);
 }
 
 static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev,
@@ -554,26 +579,39 @@ static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev,
 
 static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags)
 {
-       int data, data1;
+       int data, data1, data2, data3;
 
        if (amdgpu_sriov_vf(adev))
                *flags = 0;
 
-       data  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
-       data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
+       data = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
+       data1  = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
+       data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL);
+       data3 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL);
 
        /* AMD_CG_SUPPORT_MC_MGCG */
-       if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) &&
-           !(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
+       if (!(data & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
                       DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
                       DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
                       DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
                       DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
-                      DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)))
-               *flags |= AMD_CG_SUPPORT_MC_MGCG;
+                      DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK))
+               && !(data1 & MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK)) {
+                       *flags |= AMD_CG_SUPPORT_MC_MGCG;
+       }
 
        /* AMD_CG_SUPPORT_MC_LS */
-       if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
+       if (!(data1 & MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK)
+               && !(data2 & (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                               DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                               DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                               DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                               DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK))
+               && !(data3 & (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
+                               DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
+                               DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
+                               DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
+                               DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK)))
                *flags |= AMD_CG_SUPPORT_MC_LS;
 }
 
index 5b466f4..ab98c25 100644 (file)
@@ -251,6 +251,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
        struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
        bool force_reset = false;
        bool update_uclk = false;
+       bool p_state_change_support;
 
        if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present)
                return;
@@ -291,8 +292,9 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
                clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
 
        clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
-       if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
-               clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support;
+       p_state_change_support = new_clocks->p_state_change_support || (display_count == 0);
+       if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
+               clk_mgr_base->clks.p_state_change_support = p_state_change_support;
 
                /* to disable P-State switching, set UCLK min = max */
                if (!clk_mgr_base->clks.p_state_change_support)
index 1bd1a09..f95bade 100644 (file)
@@ -2399,6 +2399,9 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
                        initial_link_setting;
        uint32_t link_bw;
 
+       if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
+               return false;
+
        /* search for the minimum link setting that:
         * 1. is supported according to the link training result
         * 2. could support the b/w requested by the timing
@@ -3045,14 +3048,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
                for (i = 0; i < MAX_PIPES; i++) {
                        pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
                        if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
-                                       pipe_ctx->stream->link == link)
+                                       pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
                                core_link_disable_stream(pipe_ctx);
                }
 
                for (i = 0; i < MAX_PIPES; i++) {
                        pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
                        if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
-                                       pipe_ctx->stream->link == link)
+                                       pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
                                core_link_enable_stream(link->dc->current_state, pipe_ctx);
                }
 
index cfc130e..017b67b 100644 (file)
@@ -647,8 +647,13 @@ static void power_on_plane(
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
-               hws->funcs.dpp_pg_control(hws, plane_id, true);
-               hws->funcs.hubp_pg_control(hws, plane_id, true);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, plane_id, true);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, plane_id, true);
+
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 0);
                DC_LOG_DEBUG(
@@ -1082,8 +1087,13 @@ void dcn10_plane_atomic_power_down(struct dc *dc,
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
-               hws->funcs.dpp_pg_control(hws, dpp->inst, false);
-               hws->funcs.hubp_pg_control(hws, hubp->inst, false);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, dpp->inst, false);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, hubp->inst, false);
+
                dpp->funcs->dpp_reset(dpp);
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 0);
index cb822df..480d928 100644 (file)
@@ -1062,8 +1062,13 @@ static void dcn20_power_on_plane(
        if (REG(DC_IP_REQUEST_CNTL)) {
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 1);
-               dcn20_dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
-               dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
+
+               if (hws->funcs.dpp_pg_control)
+                       hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
+
+               if (hws->funcs.hubp_pg_control)
+                       hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
+
                REG_SET(DC_IP_REQUEST_CNTL, 0,
                                IP_REQUEST_EN, 0);
                DC_LOG_DEBUG(
index e04ecf0..5ed18ca 100644 (file)
@@ -2517,8 +2517,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
                 * if this primary pipe has a bottom pipe in prev. state
                 * and if the bottom pipe is still available (which it should be),
                 * pick that pipe as secondary
-                * Same logic applies for ODM pipes. Since mpo is not allowed with odm
-                * check in else case.
+                * Same logic applies for ODM pipes
                 */
                if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) {
                        preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx;
@@ -2526,7 +2525,9 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
                                secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
                                secondary_pipe->pipe_idx = preferred_pipe_idx;
                        }
-               } else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
+               }
+               if (secondary_pipe == NULL &&
+                               dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
                        preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx;
                        if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
                                secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
index 1c88d2e..b000b43 100644 (file)
@@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
        .num_banks = 8,
        .num_chans = 4,
        .vmm_page_size_bytes = 4096,
-       .dram_clock_change_latency_us = 23.84,
+       .dram_clock_change_latency_us = 11.72,
        .return_bus_width_bytes = 64,
        .dispclk_dppclk_vco_speed_mhz = 3600,
        .xfc_bus_transport_time_us = 4,
index f743685..9a96970 100644 (file)
@@ -1121,7 +1121,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
 static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
 {
 
-       return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GpuChangeState, state, NULL);
+       return 0;
 }
 
 static const struct pptable_funcs renoir_ppt_funcs = {
index ba15070..4a8cbec 100644 (file)
@@ -3021,7 +3021,7 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set,
 
        ret = handle_conflicting_encoders(state, true);
        if (ret)
-               return ret;
+               goto fail;
 
        ret = drm_atomic_commit(state);
 
index 02ca22e..0b232a7 100644 (file)
@@ -387,9 +387,16 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
        if (gbo->vmap_use_count > 0)
                goto out;
 
-       ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
-       if (ret)
-               return ret;
+       /*
+        * VRAM helpers unmap the BO only on demand. So the previous
+        * page mapping might still be around. Only vmap if the there's
+        * no mapping present.
+        */
+       if (dma_buf_map_is_null(&gbo->map)) {
+               ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
+               if (ret)
+                       return ret;
+       }
 
 out:
        ++gbo->vmap_use_count;
@@ -577,6 +584,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
                return;
 
        ttm_bo_vunmap(bo, &gbo->map);
+       dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */
 }
 
 static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo,
index 6e74e67..3491460 100644 (file)
@@ -388,19 +388,18 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
                return -ENOENT;
 
        *fence = drm_syncobj_fence_get(syncobj);
-       drm_syncobj_put(syncobj);
 
        if (*fence) {
                ret = dma_fence_chain_find_seqno(fence, point);
                if (!ret)
-                       return 0;
+                       goto out;
                dma_fence_put(*fence);
        } else {
                ret = -EINVAL;
        }
 
        if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
-               return ret;
+               goto out;
 
        memset(&wait, 0, sizeof(wait));
        wait.task = current;
@@ -432,6 +431,9 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
        if (wait.node.next)
                drm_syncobj_remove_wait(syncobj, &wait);
 
+out:
+       drm_syncobj_put(syncobj);
+
        return ret;
 }
 EXPORT_SYMBOL(drm_syncobj_find_fence);
index 92940a0..d5ace48 100644 (file)
@@ -3725,7 +3725,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        intel_ddi_init_dp_buf_reg(encoder, crtc_state);
        if (!is_mst)
                intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-       intel_dp_configure_protocol_converter(intel_dp);
+       intel_dp_configure_protocol_converter(intel_dp, crtc_state);
        intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
                                              true);
        intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
index 37f1a10..09123e8 100644 (file)
@@ -4014,7 +4014,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
        intel_de_posting_read(dev_priv, intel_dp->output_reg);
 }
 
-void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
+                                          const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
        u8 tmp;
@@ -4033,8 +4034,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
                drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n",
                            enableddisabled(intel_dp->has_hdmi_sink));
 
-       tmp = intel_dp->dfp.ycbcr_444_to_420 ?
-               DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
+       tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
+               intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
 
        if (drm_dp_dpcd_writeb(&intel_dp->aux,
                               DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
@@ -4088,7 +4089,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
        }
 
        intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
-       intel_dp_configure_protocol_converter(intel_dp);
+       intel_dp_configure_protocol_converter(intel_dp, pipe_config);
        intel_dp_start_link_train(intel_dp, pipe_config);
        intel_dp_stop_link_train(intel_dp, pipe_config);
 
index b871a09..05f7ddf 100644 (file)
@@ -51,7 +51,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 int intel_dp_retrain_link(struct intel_encoder *encoder,
                          struct drm_modeset_acquire_ctx *ctx);
 void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
-void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp);
+void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
+                                          const struct intel_crtc_state *crtc_state);
 void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
                                           const struct intel_crtc_state *crtc_state,
                                           bool enable);
index b2a4bbc..b9d8825 100644 (file)
@@ -2210,6 +2210,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
        if (content_protection_type_changed) {
                mutex_lock(&hdcp->mutex);
                hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+               drm_connector_get(&connector->base);
                schedule_work(&hdcp->prop_work);
                mutex_unlock(&hdcp->mutex);
        }
@@ -2221,6 +2222,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                desired_and_not_enabled =
                        hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED;
                mutex_unlock(&hdcp->mutex);
+               /*
+                * If HDCP already ENABLED and CP property is DESIRED, schedule
+                * prop_work to update correct CP property to user space.
+                */
+               if (!desired_and_not_enabled && !content_protection_type_changed) {
+                       drm_connector_get(&connector->base);
+                       schedule_work(&hdcp->prop_work);
+               }
        }
 
        if (desired_and_not_enabled || content_protection_type_changed)
index a24cc1f..0625cbb 100644 (file)
@@ -134,11 +134,6 @@ static bool remove_signaling_context(struct intel_breadcrumbs *b,
        return true;
 }
 
-static inline bool __request_completed(const struct i915_request *rq)
-{
-       return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
-}
-
 __maybe_unused static bool
 check_signal_order(struct intel_context *ce, struct i915_request *rq)
 {
@@ -257,7 +252,7 @@ static void signal_irq_work(struct irq_work *work)
                list_for_each_entry_rcu(rq, &ce->signals, signal_link) {
                        bool release;
 
-                       if (!__request_completed(rq))
+                       if (!__i915_request_is_complete(rq))
                                break;
 
                        if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL,
@@ -379,7 +374,7 @@ static void insert_breadcrumb(struct i915_request *rq)
         * straight onto a signaled list, and queue the irq worker for
         * its signal completion.
         */
-       if (__request_completed(rq)) {
+       if (__i915_request_is_complete(rq)) {
                if (__signal_request(rq) &&
                    llist_add(&rq->signal_node, &b->signaled_requests))
                        irq_work_queue(&b->irq_work);
index 7614a3d..26c7d0a 100644 (file)
@@ -3988,6 +3988,9 @@ err:
 static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine)
 {
        i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
+
+       /* Called on error unwind, clear all flags to prevent further use */
+       memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx));
 }
 
 typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);
index 7ea94d2..8015964 100644 (file)
@@ -126,6 +126,10 @@ static void __rcu_cacheline_free(struct rcu_head *rcu)
        struct intel_timeline_cacheline *cl =
                container_of(rcu, typeof(*cl), rcu);
 
+       /* Must wait until after all *rq->hwsp are complete before removing */
+       i915_gem_object_unpin_map(cl->hwsp->vma->obj);
+       __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
+
        i915_active_fini(&cl->active);
        kfree(cl);
 }
@@ -133,11 +137,6 @@ static void __rcu_cacheline_free(struct rcu_head *rcu)
 static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
 {
        GEM_BUG_ON(!i915_active_is_idle(&cl->active));
-
-       i915_gem_object_unpin_map(cl->hwsp->vma->obj);
-       i915_vma_put(cl->hwsp->vma);
-       __idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
-
        call_rcu(&cl->rcu, __rcu_cacheline_free);
 }
 
@@ -179,7 +178,6 @@ cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline)
                return ERR_CAST(vaddr);
        }
 
-       i915_vma_get(hwsp->vma);
        cl->hwsp = hwsp;
        cl->vaddr = page_pack_bits(vaddr, cacheline);
 
index d76685c..9856479 100644 (file)
@@ -184,13 +184,24 @@ static u64 get_rc6(struct intel_gt *gt)
        return val;
 }
 
-static void park_rc6(struct drm_i915_private *i915)
+static void init_rc6(struct i915_pmu *pmu)
 {
-       struct i915_pmu *pmu = &i915->pmu;
+       struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu);
+       intel_wakeref_t wakeref;
 
-       if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY))
+       with_intel_runtime_pm(i915->gt.uncore->rpm, wakeref) {
                pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
+               pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur =
+                                       pmu->sample[__I915_SAMPLE_RC6].cur;
+               pmu->sleep_last = ktime_get();
+       }
+}
 
+static void park_rc6(struct drm_i915_private *i915)
+{
+       struct i915_pmu *pmu = &i915->pmu;
+
+       pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
        pmu->sleep_last = ktime_get();
 }
 
@@ -201,6 +212,7 @@ static u64 get_rc6(struct intel_gt *gt)
        return __get_rc6(gt);
 }
 
+static void init_rc6(struct i915_pmu *pmu) { }
 static void park_rc6(struct drm_i915_private *i915) {}
 
 #endif
@@ -612,10 +624,8 @@ static void i915_pmu_enable(struct perf_event *event)
                container_of(event->pmu, typeof(*i915), pmu.base);
        unsigned int bit = event_enabled_bit(event);
        struct i915_pmu *pmu = &i915->pmu;
-       intel_wakeref_t wakeref;
        unsigned long flags;
 
-       wakeref = intel_runtime_pm_get(&i915->runtime_pm);
        spin_lock_irqsave(&pmu->lock, flags);
 
        /*
@@ -626,13 +636,6 @@ static void i915_pmu_enable(struct perf_event *event)
        GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count));
        GEM_BUG_ON(pmu->enable_count[bit] == ~0);
 
-       if (pmu->enable_count[bit] == 0 &&
-           config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) {
-               pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0;
-               pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
-               pmu->sleep_last = ktime_get();
-       }
-
        pmu->enable |= BIT_ULL(bit);
        pmu->enable_count[bit]++;
 
@@ -673,8 +676,6 @@ static void i915_pmu_enable(struct perf_event *event)
         * an existing non-zero value.
         */
        local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
-
-       intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 }
 
 static void i915_pmu_disable(struct perf_event *event)
@@ -1130,6 +1131,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
        hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        pmu->timer.function = i915_sample;
        pmu->cpuhp.cpu = -1;
+       init_rc6(pmu);
 
        if (!is_igp(i915)) {
                pmu->name = kasprintf(GFP_KERNEL,
index 620b6fa..92adfee 100644 (file)
@@ -434,7 +434,7 @@ static inline u32 hwsp_seqno(const struct i915_request *rq)
 
 static inline bool __i915_request_has_started(const struct i915_request *rq)
 {
-       return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1);
+       return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno - 1);
 }
 
 /**
@@ -465,11 +465,19 @@ static inline bool __i915_request_has_started(const struct i915_request *rq)
  */
 static inline bool i915_request_started(const struct i915_request *rq)
 {
+       bool result;
+
        if (i915_request_signaled(rq))
                return true;
 
-       /* Remember: started but may have since been preempted! */
-       return __i915_request_has_started(rq);
+       result = true;
+       rcu_read_lock(); /* the HWSP may be freed at runtime */
+       if (likely(!i915_request_signaled(rq)))
+               /* Remember: started but may have since been preempted! */
+               result = __i915_request_has_started(rq);
+       rcu_read_unlock();
+
+       return result;
 }
 
 /**
@@ -482,10 +490,16 @@ static inline bool i915_request_started(const struct i915_request *rq)
  */
 static inline bool i915_request_is_running(const struct i915_request *rq)
 {
+       bool result;
+
        if (!i915_request_is_active(rq))
                return false;
 
-       return __i915_request_has_started(rq);
+       rcu_read_lock();
+       result = __i915_request_has_started(rq) && i915_request_is_active(rq);
+       rcu_read_unlock();
+
+       return result;
 }
 
 /**
@@ -509,12 +523,25 @@ static inline bool i915_request_is_ready(const struct i915_request *rq)
        return !list_empty(&rq->sched.link);
 }
 
+static inline bool __i915_request_is_complete(const struct i915_request *rq)
+{
+       return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
+}
+
 static inline bool i915_request_completed(const struct i915_request *rq)
 {
+       bool result;
+
        if (i915_request_signaled(rq))
                return true;
 
-       return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno);
+       result = true;
+       rcu_read_lock(); /* the HWSP may be freed at runtime */
+       if (likely(!i915_request_signaled(rq)))
+               result = __i915_request_is_complete(rq);
+       rcu_read_unlock();
+
+       return result;
 }
 
 static inline void i915_request_mark_complete(struct i915_request *rq)
index 8cd776a..11e0313 100644 (file)
@@ -79,12 +79,13 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
        struct page *p;
        void *vaddr;
 
-       if (order) {
-               gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
+       /* Don't set the __GFP_COMP flag for higher order allocations.
+        * Mapping pages directly into an userspace process and calling
+        * put_page() on a TTM allocated page is illegal.
+        */
+       if (order)
+               gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY |
                        __GFP_KSWAPD_RECLAIM;
-               gfp_flags &= ~__GFP_MOVABLE;
-               gfp_flags &= ~__GFP_COMP;
-       }
 
        if (!pool->use_dma_alloc) {
                p = alloc_pages(gfp_flags, order);
index 5551062..98cab0b 100644 (file)
@@ -1267,6 +1267,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
        card->dai_link = dai_link;
        card->num_links = 1;
        card->name = vc4_hdmi->variant->card_name;
+       card->driver_name = "vc4-hdmi";
        card->dev = dev;
        card->owner = THIS_MODULE;
 
index d4d60ad..ab1f39a 100644 (file)
@@ -1013,6 +1013,7 @@ config I2C_SIRF
 config I2C_SPRD
        tristate "Spreadtrum I2C interface"
        depends on I2C=y && (ARCH_SPRD || COMPILE_TEST)
+       depends on COMMON_CLK
        help
          If you say yes to this option, support will be included for the
          Spreadtrum I2C interface.
index b444fbf..a8e8af5 100644 (file)
@@ -241,6 +241,19 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
 
 };
 
+static const struct platform_device_id imx_i2c_devtype[] = {
+       {
+               .name = "imx1-i2c",
+               .driver_data = (kernel_ulong_t)&imx1_i2c_hwdata,
+       }, {
+               .name = "imx21-i2c",
+               .driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
+
 static const struct of_device_id i2c_imx_dt_ids[] = {
        { .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
        { .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
@@ -1330,7 +1343,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        match = device_get_match_data(&pdev->dev);
-       i2c_imx->hwdata = match;
+       if (match)
+               i2c_imx->hwdata = match;
+       else
+               i2c_imx->hwdata = (struct imx_i2c_hwdata *)
+                               platform_get_device_id(pdev)->driver_data;
 
        /* Setup i2c_imx driver structure */
        strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
@@ -1498,6 +1515,7 @@ static struct platform_driver i2c_imx_driver = {
                .of_match_table = i2c_imx_dt_ids,
                .acpi_match_table = i2c_imx_acpi_ids,
        },
+       .id_table = imx_i2c_devtype,
 };
 
 static int __init i2c_adap_imx_init(void)
index d960790..845eda7 100644 (file)
@@ -347,7 +347,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
                if (result)
                        return result;
                if (recv_len && i == 0) {
-                       if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
+                       if (data[i] > I2C_SMBUS_BLOCK_MAX)
                                return -EPROTO;
                        length += data[i];
                }
index ec7a7e9..c0c7d01 100644 (file)
@@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 flags, u16 *out)
                flags &= ~I2C_M_RECV_LEN;
        }
 
-       return (flags != 0) ? -EINVAL : 0;
+       return 0;
 }
 
 /**
index 6f08c0c..8b113ae 100644 (file)
@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg)
        /* read back register to make sure that register writes completed */
        if (reg != I2C_TX_FIFO)
                readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+       else if (i2c_dev->is_vi)
+               readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS));
 }
 
 static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
        writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
 
+static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
+                          unsigned int reg, unsigned int len)
+{
+       u32 *data32 = data;
+
+       /*
+        * VI I2C controller has known hardware bug where writes get stuck
+        * when immediate multiple writes happen to TX_FIFO register.
+        * Recommended software work around is to read I2C register after
+        * each write to TX_FIFO register to flush out the data.
+        */
+       while (len--)
+               i2c_writel(i2c_dev, *data32++, reg);
+}
+
 static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
                       unsigned int reg, unsigned int len)
 {
@@ -533,7 +550,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
        void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
        u32 val;
 
-       if (!i2c_dev->atomic_mode)
+       if (!i2c_dev->atomic_mode && !in_irq())
                return readl_relaxed_poll_timeout(addr, val, !(val & mask),
                                                  delay_us, timeout_us);
 
@@ -811,7 +828,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
                i2c_dev->msg_buf_remaining = buf_remaining;
                i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
 
-               i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+               if (i2c_dev->is_vi)
+                       i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+               else
+                       i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
 
                buf += words_to_transfer * BYTES_PER_FIFO_WORD;
        }
index 8c87471..5a55617 100644 (file)
@@ -1481,9 +1481,9 @@ static int crypt_alloc_req_skcipher(struct crypt_config *cc,
 static int crypt_alloc_req_aead(struct crypt_config *cc,
                                 struct convert_context *ctx)
 {
-       if (!ctx->r.req) {
-               ctx->r.req = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
-               if (!ctx->r.req)
+       if (!ctx->r.req_aead) {
+               ctx->r.req_aead = mempool_alloc(&cc->req_pool, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+               if (!ctx->r.req_aead)
                        return -ENOMEM;
        }
 
index 81df019..b64fede 100644 (file)
@@ -257,8 +257,9 @@ struct dm_integrity_c {
        bool journal_uptodate;
        bool just_formatted;
        bool recalculate_flag;
-       bool fix_padding;
        bool discard;
+       bool fix_padding;
+       bool legacy_recalculate;
 
        struct alg_spec internal_hash_alg;
        struct alg_spec journal_crypt_alg;
@@ -386,6 +387,14 @@ static int dm_integrity_failed(struct dm_integrity_c *ic)
        return READ_ONCE(ic->failed);
 }
 
+static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic)
+{
+       if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) &&
+           !ic->legacy_recalculate)
+               return true;
+       return false;
+}
+
 static commit_id_t dm_integrity_commit_id(struct dm_integrity_c *ic, unsigned i,
                                          unsigned j, unsigned char seq)
 {
@@ -3140,6 +3149,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
                arg_count += !!ic->journal_crypt_alg.alg_string;
                arg_count += !!ic->journal_mac_alg.alg_string;
                arg_count += (ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0;
+               arg_count += ic->legacy_recalculate;
                DMEMIT("%s %llu %u %c %u", ic->dev->name, ic->start,
                       ic->tag_size, ic->mode, arg_count);
                if (ic->meta_dev)
@@ -3163,6 +3173,8 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
                }
                if ((ic->sb->flags & cpu_to_le32(SB_FLAG_FIXED_PADDING)) != 0)
                        DMEMIT(" fix_padding");
+               if (ic->legacy_recalculate)
+                       DMEMIT(" legacy_recalculate");
 
 #define EMIT_ALG(a, n)                                                 \
                do {                                                    \
@@ -3792,7 +3804,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        unsigned extra_args;
        struct dm_arg_set as;
        static const struct dm_arg _args[] = {
-               {0, 15, "Invalid number of feature args"},
+               {0, 16, "Invalid number of feature args"},
        };
        unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec;
        bool should_write_sb;
@@ -3940,6 +3952,8 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
                        ic->discard = true;
                } else if (!strcmp(opt_string, "fix_padding")) {
                        ic->fix_padding = true;
+               } else if (!strcmp(opt_string, "legacy_recalculate")) {
+                       ic->legacy_recalculate = true;
                } else {
                        r = -EINVAL;
                        ti->error = "Invalid argument";
@@ -4235,6 +4249,20 @@ try_smaller_buffer:
                        r = -ENOMEM;
                        goto bad;
                }
+       } else {
+               if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) {
+                       ti->error = "Recalculate can only be specified with internal_hash";
+                       r = -EINVAL;
+                       goto bad;
+               }
+       }
+
+       if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
+           le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors &&
+           dm_integrity_disable_recalculate(ic)) {
+               ti->error = "Recalculating with HMAC is disabled for security reasons - if you really need it, use the argument \"legacy_recalculate\"";
+               r = -EOPNOTSUPP;
+               goto bad;
        }
 
        ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev,
index 188f412..4acf234 100644 (file)
@@ -363,14 +363,23 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
 {
        int r;
        dev_t dev;
+       unsigned int major, minor;
+       char dummy;
        struct dm_dev_internal *dd;
        struct dm_table *t = ti->table;
 
        BUG_ON(!t);
 
-       dev = dm_get_dev_t(path);
-       if (!dev)
-               return -ENODEV;
+       if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) {
+               /* Extract the major/minor numbers */
+               dev = MKDEV(major, minor);
+               if (MAJOR(dev) != major || MINOR(dev) != minor)
+                       return -EOVERFLOW;
+       } else {
+               dev = dm_get_dev_t(path);
+               if (!dev)
+                       return -ENODEV;
+       }
 
        dd = find_device(&t->devices, dev);
        if (!dd) {
index de7cb03..002426e 100644 (file)
@@ -384,8 +384,10 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
                     "merging was advertised but not possible");
        blk_queue_max_segments(mq->queue, mmc_get_max_segments(host));
 
-       if (mmc_card_mmc(card))
+       if (mmc_card_mmc(card) && card->ext_csd.data_sector_size) {
                block_size = card->ext_csd.data_sector_size;
+               WARN_ON(block_size != 512 && block_size != 4096);
+       }
 
        blk_queue_logical_block_size(mq->queue, block_size);
        /*
index bbf3496..f9780c6 100644 (file)
@@ -314,11 +314,7 @@ err_clk:
 
 static void sdhci_brcmstb_shutdown(struct platform_device *pdev)
 {
-       int ret;
-
-       ret = sdhci_pltfm_unregister(pdev);
-       if (ret)
-               dev_err(&pdev->dev, "failed to shutdown\n");
+       sdhci_pltfm_suspend(&pdev->dev);
 }
 
 MODULE_DEVICE_TABLE(of, sdhci_brcm_of_match);
index 4b67379..d90020e 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "sdhci-pltfm.h"
 
+#define SDHCI_DWCMSHC_ARG2_STUFF       GENMASK(31, 16)
+
 /* DWCMSHC specific Mode Select value */
 #define DWCMSHC_CTRL_HS400             0x7
 
@@ -49,6 +51,29 @@ static void dwcmshc_adma_write_desc(struct sdhci_host *host, void **desc,
        sdhci_adma_write_desc(host, desc, addr, len, cmd);
 }
 
+static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,
+                                    struct mmc_request *mrq)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       /*
+        * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit
+        * block count register which doesn't support stuff bits of
+        * CMD23 argument on dwcmsch host controller.
+        */
+       if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF))
+               host->flags &= ~SDHCI_AUTO_CMD23;
+       else
+               host->flags |= SDHCI_AUTO_CMD23;
+}
+
+static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+       dwcmshc_check_auto_cmd23(mmc, mrq);
+
+       sdhci_request(mmc, mrq);
+}
+
 static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
                                      unsigned int timing)
 {
@@ -133,6 +158,8 @@ static int dwcmshc_probe(struct platform_device *pdev)
 
        sdhci_get_of_property(pdev);
 
+       host->mmc_host_ops.request = dwcmshc_request;
+
        err = sdhci_add_host(host);
        if (err)
                goto err_clk;
index c67611f..d19eef5 100644 (file)
@@ -168,7 +168,12 @@ static void xenon_reset_exit(struct sdhci_host *host,
        /* Disable tuning request and auto-retuning again */
        xenon_retune_setup(host);
 
-       xenon_set_acg(host, true);
+       /*
+        * The ACG should be turned off at the early init time, in order
+        * to solve a possible issues with the 1.8V regulator stabilization.
+        * The feature is enabled in later stage.
+        */
+       xenon_set_acg(host, false);
 
        xenon_set_sdclk_off_idle(host, sdhc_id, false);
 
index 5cdf05b..3fa8c22 100644 (file)
@@ -1615,7 +1615,7 @@ static int gpmi_ecc_read_page_raw(struct nand_chip *chip, uint8_t *buf,
        /* Extract interleaved payload data and ECC bits */
        for (step = 0; step < nfc_geo->ecc_chunk_count; step++) {
                if (buf)
-                       nand_extract_bits(buf, step * eccsize, tmp_buf,
+                       nand_extract_bits(buf, step * eccsize * 8, tmp_buf,
                                          src_bit_off, eccsize * 8);
                src_bit_off += eccsize * 8;
 
index fdb112e..a304fda 100644 (file)
@@ -579,7 +579,7 @@ static int ebu_nand_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct ebu_nand_controller *ebu_host;
        struct nand_chip *nand;
-       struct mtd_info *mtd = NULL;
+       struct mtd_info *mtd;
        struct resource *res;
        char *resname;
        int ret;
@@ -647,12 +647,13 @@ static int ebu_nand_probe(struct platform_device *pdev)
               ebu_host->ebu + EBU_ADDR_SEL(cs));
 
        nand_set_flash_node(&ebu_host->chip, dev->of_node);
+
+       mtd = nand_to_mtd(&ebu_host->chip);
        if (!mtd->name) {
                dev_err(ebu_host->dev, "NAND label property is mandatory\n");
                return -EINVAL;
        }
 
-       mtd = nand_to_mtd(&ebu_host->chip);
        mtd->dev.parent = dev;
        ebu_host->dev = dev;
 
index f2b9250..0750121 100644 (file)
@@ -2210,6 +2210,9 @@ static int ns_attach_chip(struct nand_chip *chip)
 {
        unsigned int eccsteps, eccbytes;
 
+       chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+       chip->ecc.algo = bch ? NAND_ECC_ALGO_BCH : NAND_ECC_ALGO_HAMMING;
+
        if (!bch)
                return 0;
 
@@ -2233,8 +2236,6 @@ static int ns_attach_chip(struct nand_chip *chip)
                return -EINVAL;
        }
 
-       chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-       chip->ecc.algo = NAND_ECC_ALGO_BCH;
        chip->ecc.size = 512;
        chip->ecc.strength = bch;
        chip->ecc.bytes = eccbytes;
@@ -2273,8 +2274,6 @@ static int __init ns_init_module(void)
        nsmtd       = nand_to_mtd(chip);
        nand_set_controller_data(chip, (void *)ns);
 
-       chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-       chip->ecc.algo   = NAND_ECC_ALGO_HAMMING;
        /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */
        /* and 'badblocks' parameters to work */
        chip->options   |= NAND_SKIP_BBTSCAN;
index fbb9955..2c3e65c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/jiffies.h>
 #include <linux/sched.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/nand-ecc-sw-bch.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/omap-dma.h>
@@ -1866,18 +1867,19 @@ static const struct mtd_ooblayout_ops omap_ooblayout_ops = {
 static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section,
                                 struct mtd_oob_region *oobregion)
 {
-       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct nand_device *nand = mtd_to_nanddev(mtd);
+       const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv;
        int off = BADBLOCK_MARKER_LENGTH;
 
-       if (section >= chip->ecc.steps)
+       if (section >= engine_conf->nsteps)
                return -ERANGE;
 
        /*
         * When SW correction is employed, one OMAP specific marker byte is
         * reserved after each ECC step.
         */
-       oobregion->offset = off + (section * (chip->ecc.bytes + 1));
-       oobregion->length = chip->ecc.bytes;
+       oobregion->offset = off + (section * (engine_conf->code_size + 1));
+       oobregion->length = engine_conf->code_size;
 
        return 0;
 }
@@ -1885,7 +1887,8 @@ static int omap_sw_ooblayout_ecc(struct mtd_info *mtd, int section,
 static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
                                  struct mtd_oob_region *oobregion)
 {
-       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct nand_device *nand = mtd_to_nanddev(mtd);
+       const struct nand_ecc_sw_bch_conf *engine_conf = nand->ecc.ctx.priv;
        int off = BADBLOCK_MARKER_LENGTH;
 
        if (section)
@@ -1895,7 +1898,7 @@ static int omap_sw_ooblayout_free(struct mtd_info *mtd, int section,
         * When SW correction is employed, one OMAP specific marker byte is
         * reserved after each ECC step.
         */
-       off += ((chip->ecc.bytes + 1) * chip->ecc.steps);
+       off += ((engine_conf->code_size + 1) * engine_conf->nsteps);
        if (off >= mtd->oobsize)
                return -ERANGE;
 
index 8ea545b..61d932c 100644 (file)
@@ -343,6 +343,7 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
                                      const struct nand_page_io_req *req)
 {
        struct nand_device *nand = spinand_to_nand(spinand);
+       struct mtd_info *mtd = spinand_to_mtd(spinand);
        struct spi_mem_dirmap_desc *rdesc;
        unsigned int nbytes = 0;
        void *buf = NULL;
@@ -382,9 +383,16 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand,
                memcpy(req->databuf.in, spinand->databuf + req->dataoffs,
                       req->datalen);
 
-       if (req->ooblen)
-               memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
-                      req->ooblen);
+       if (req->ooblen) {
+               if (req->mode == MTD_OPS_AUTO_OOB)
+                       mtd_ooblayout_get_databytes(mtd, req->oobbuf.in,
+                                                   spinand->oobbuf,
+                                                   req->ooboffs,
+                                                   req->ooblen);
+               else
+                       memcpy(req->oobbuf.in, spinand->oobbuf + req->ooboffs,
+                              req->ooblen);
+       }
 
        return 0;
 }
index 3486704..8b1ae02 100644 (file)
@@ -592,11 +592,11 @@ static void can_restart(struct net_device *dev)
 
        cf->can_id |= CAN_ERR_RESTARTED;
 
-       netif_rx_ni(skb);
-
        stats->rx_packets++;
        stats->rx_bytes += cf->len;
 
+       netif_rx_ni(skb);
+
 restart:
        netdev_dbg(dev, "restarted\n");
        priv->can_stats.restarts++;
index 61631f4..f347ecc 100644 (file)
@@ -514,11 +514,11 @@ static int pcan_usb_fd_decode_canmsg(struct pcan_usb_fd_if *usb_if,
        else
                memcpy(cfd->data, rm->d, cfd->len);
 
-       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
-
        netdev->stats.rx_packets++;
        netdev->stats.rx_bytes += cfd->len;
 
+       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low));
+
        return 0;
 }
 
@@ -580,11 +580,11 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
        if (!skb)
                return -ENOMEM;
 
-       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
-
        netdev->stats.rx_packets++;
        netdev->stats.rx_bytes += cf->len;
 
+       peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low));
+
        return 0;
 }
 
index fa47bab..f9a524c 100644 (file)
@@ -39,6 +39,7 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_device *peer;
        struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
        struct net_device_stats *peerstats, *srcstats = &dev->stats;
+       u8 len;
 
        if (can_dropped_invalid_skb(dev, skb))
                return NETDEV_TX_OK;
@@ -61,12 +62,13 @@ static netdev_tx_t vxcan_xmit(struct sk_buff *skb, struct net_device *dev)
        skb->dev        = peer;
        skb->ip_summed  = CHECKSUM_UNNECESSARY;
 
+       len = cfd->len;
        if (netif_rx_ni(skb) == NET_RX_SUCCESS) {
                srcstats->tx_packets++;
-               srcstats->tx_bytes += cfd->len;
+               srcstats->tx_bytes += len;
                peerstats = &peer->stats;
                peerstats->rx_packets++;
-               peerstats->rx_bytes += cfd->len;
+               peerstats->rx_bytes += len;
        }
 
 out_unlock:
index 288b5a5..95c7fa1 100644 (file)
@@ -1404,7 +1404,7 @@ int b53_vlan_prepare(struct dsa_switch *ds, int port,
            !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED))
                return -EINVAL;
 
-       if (vlan->vid_end > dev->num_vlans)
+       if (vlan->vid_end >= dev->num_vlans)
                return -ERANGE;
 
        b53_enable_vlan(dev, true, ds->vlan_filtering);
index 66ddf67..7b96396 100644 (file)
@@ -351,6 +351,10 @@ int mv88e6250_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
                if (err)
                        return err;
 
+               err = mv88e6185_g1_stu_data_read(chip, entry);
+               if (err)
+                       return err;
+
                /* VTU DBNum[3:0] are located in VTU Operation 3:0
                 * VTU DBNum[5:4] are located in VTU Operation 9:8
                 */
index b1ae9eb..0404aaf 100644 (file)
@@ -2503,8 +2503,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
        priv = netdev_priv(dev);
 
        priv->clk = devm_clk_get_optional(&pdev->dev, "sw_sysport");
-       if (IS_ERR(priv->clk))
-               return PTR_ERR(priv->clk);
+       if (IS_ERR(priv->clk)) {
+               ret = PTR_ERR(priv->clk);
+               goto err_free_netdev;
+       }
 
        /* Allocate number of TX rings */
        priv->tx_rings = devm_kcalloc(&pdev->dev, txq,
index d298b93..6c6b411 100644 (file)
@@ -469,6 +469,9 @@ int rvu_mbox_handler_cgx_mac_addr_set(struct rvu *rvu,
        int pf = rvu_get_pf(req->hdr.pcifunc);
        u8 cgx_id, lmac_id;
 
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
        rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
 
        cgx_lmac_addr_set(cgx_id, lmac_id, req->mac_addr);
@@ -485,6 +488,9 @@ int rvu_mbox_handler_cgx_mac_addr_get(struct rvu *rvu,
        int rc = 0, i;
        u64 cfg;
 
+       if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+               return -EPERM;
+
        rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
 
        rsp->hdr.rc = rc;
index 0b9992b..ff87a0b 100644 (file)
@@ -60,14 +60,27 @@ int ocelot_mact_learn(struct ocelot *ocelot, int port,
                      const unsigned char mac[ETH_ALEN],
                      unsigned int vid, enum macaccess_entry_type type)
 {
+       u32 cmd = ANA_TABLES_MACACCESS_VALID |
+               ANA_TABLES_MACACCESS_DEST_IDX(port) |
+               ANA_TABLES_MACACCESS_ENTRYTYPE(type) |
+               ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN);
+       unsigned int mc_ports;
+
+       /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */
+       if (type == ENTRYTYPE_MACv4)
+               mc_ports = (mac[1] << 8) | mac[2];
+       else if (type == ENTRYTYPE_MACv6)
+               mc_ports = (mac[0] << 8) | mac[1];
+       else
+               mc_ports = 0;
+
+       if (mc_ports & BIT(ocelot->num_phys_ports))
+               cmd |= ANA_TABLES_MACACCESS_MAC_CPU_COPY;
+
        ocelot_mact_select(ocelot, mac, vid);
 
        /* Issue a write command */
-       ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID |
-                            ANA_TABLES_MACACCESS_DEST_IDX(port) |
-                            ANA_TABLES_MACACCESS_ENTRYTYPE(type) |
-                            ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
-                            ANA_TABLES_MACACCESS);
+       ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS);
 
        return ocelot_mact_wait_for_completion(ocelot);
 }
index 2bd2840..42230f9 100644 (file)
@@ -1042,10 +1042,8 @@ static int ocelot_netdevice_event(struct notifier_block *unused,
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        int ret = 0;
 
-       if (!ocelot_netdevice_dev_check(dev))
-               return 0;
-
        if (event == NETDEV_PRECHANGEUPPER &&
+           ocelot_netdevice_dev_check(dev) &&
            netif_is_lag_master(info->upper_dev)) {
                struct netdev_lag_upper_info *lag_upper_info = info->upper_info;
                struct netlink_ext_ack *extack;
index c633046..590b088 100644 (file)
@@ -2606,10 +2606,10 @@ static int sh_eth_close(struct net_device *ndev)
        /* Free all the skbuffs in the Rx queue and the DMA buffer. */
        sh_eth_ring_free(ndev);
 
-       pm_runtime_put_sync(&mdp->pdev->dev);
-
        mdp->is_opened = 0;
 
+       pm_runtime_put(&mdp->pdev->dev);
+
        return 0;
 }
 
@@ -3034,6 +3034,28 @@ static int sh_mdio_release(struct sh_eth_private *mdp)
        return 0;
 }
 
+static int sh_mdiobb_read(struct mii_bus *bus, int phy, int reg)
+{
+       int res;
+
+       pm_runtime_get_sync(bus->parent);
+       res = mdiobb_read(bus, phy, reg);
+       pm_runtime_put(bus->parent);
+
+       return res;
+}
+
+static int sh_mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+       int res;
+
+       pm_runtime_get_sync(bus->parent);
+       res = mdiobb_write(bus, phy, reg, val);
+       pm_runtime_put(bus->parent);
+
+       return res;
+}
+
 /* MDIO bus init function */
 static int sh_mdio_init(struct sh_eth_private *mdp,
                        struct sh_eth_plat_data *pd)
@@ -3058,6 +3080,10 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
        if (!mdp->mii_bus)
                return -ENOMEM;
 
+       /* Wrap accessors with Runtime PM-aware ops */
+       mdp->mii_bus->read = sh_mdiobb_read;
+       mdp->mii_bus->write = sh_mdiobb_write;
+
        /* Hook up MII support for ethtool */
        mdp->mii_bus->name = "sh_mii";
        mdp->mii_bus->parent = dev;
index 5136275..d3915f8 100644 (file)
@@ -149,7 +149,7 @@ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
        return dev_addr;
 }
 
-static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
+int mdiobb_read(struct mii_bus *bus, int phy, int reg)
 {
        struct mdiobb_ctrl *ctrl = bus->priv;
        int ret, i;
@@ -180,8 +180,9 @@ static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
        mdiobb_get_bit(ctrl);
        return ret;
 }
+EXPORT_SYMBOL(mdiobb_read);
 
-static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
+int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
 {
        struct mdiobb_ctrl *ctrl = bus->priv;
 
@@ -201,6 +202,7 @@ static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
        mdiobb_get_bit(ctrl);
        return 0;
 }
+EXPORT_SYMBOL(mdiobb_write);
 
 struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
 {
index 5a78848..291e76d 100644 (file)
@@ -1827,6 +1827,15 @@ cdc_ncm_speed_change(struct usbnet *dev,
        uint32_t rx_speed = le32_to_cpu(data->DLBitRRate);
        uint32_t tx_speed = le32_to_cpu(data->ULBitRate);
 
+       /* if the speed hasn't changed, don't report it.
+        * RTL8156 shipped before 2021 sends notification about every 32ms.
+        */
+       if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed)
+               return;
+
+       dev->rx_speed = rx_speed;
+       dev->tx_speed = tx_speed;
+
        /*
         * Currently the USB-NET API does not support reporting the actual
         * device speed. Do print it instead.
@@ -1867,7 +1876,8 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
                 * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
                 * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE.
                 */
-               usbnet_link_change(dev, !!event->wValue, 0);
+               if (netif_carrier_ok(dev->net) != !!event->wValue)
+                       usbnet_link_change(dev, !!event->wValue, 0);
                break;
 
        case USB_CDC_NOTIFY_SPEED_CHANGE:
index 34803a6..5c1a109 100644 (file)
@@ -347,7 +347,7 @@ FUNC_GROUP_DECL(RMII4, F24, E23, E24, E25, C25, C24, B26, B25, B24);
 
 #define D22 40
 SIG_EXPR_LIST_DECL_SESG(D22, SD1CLK, SD1, SIG_DESC_SET(SCU414, 8));
-SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU414, 8));
+SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU4B4, 8));
 PIN_DECL_2(D22, GPIOF0, SD1CLK, PWM8);
 GROUP_DECL(PWM8G0, D22);
 
index 7aeb552..72f17f2 100644 (file)
@@ -920,6 +920,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
                        err = hw->soc->bias_set(hw, desc, pullup);
                        if (err)
                                return err;
+               } else if (hw->soc->bias_set_combo) {
+                       err = hw->soc->bias_set_combo(hw, desc, pullup, arg);
+                       if (err)
+                               return err;
                } else {
                        return -ENOTSUPP;
                }
index d4ea108..abfe11c 100644 (file)
@@ -949,7 +949,6 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
        } else {
                int irq = chip->to_irq(chip, offset);
                const int pullidx = pull ? 1 : 0;
-               bool wake;
                int val;
                static const char * const pulls[] = {
                        "none        ",
index 53a6a24..3ea1634 100644 (file)
 #define JZ4740_GPIO_TRIG       0x70
 #define JZ4740_GPIO_FLAG       0x80
 
-#define JZ4760_GPIO_INT                0x10
-#define JZ4760_GPIO_PAT1       0x30
-#define JZ4760_GPIO_PAT0       0x40
-#define JZ4760_GPIO_FLAG       0x50
-#define JZ4760_GPIO_PEN                0x70
+#define JZ4770_GPIO_INT                0x10
+#define JZ4770_GPIO_PAT1       0x30
+#define JZ4770_GPIO_PAT0       0x40
+#define JZ4770_GPIO_FLAG       0x50
+#define JZ4770_GPIO_PEN                0x70
 
 #define X1830_GPIO_PEL                 0x110
 #define X1830_GPIO_PEH                 0x120
@@ -1688,8 +1688,8 @@ static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
 static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
                                   u8 offset, int value)
 {
-       if (jzgc->jzpc->info->version >= ID_JZ4760)
-               ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value);
+       if (jzgc->jzpc->info->version >= ID_JZ4770)
+               ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
        else
                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
 }
@@ -1718,9 +1718,9 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc,
                break;
        }
 
-       if (jzgc->jzpc->info->version >= ID_JZ4760) {
-               reg1 = JZ4760_GPIO_PAT1;
-               reg2 = JZ4760_GPIO_PAT0;
+       if (jzgc->jzpc->info->version >= ID_JZ4770) {
+               reg1 = JZ4770_GPIO_PAT1;
+               reg2 = JZ4770_GPIO_PAT0;
        } else {
                reg1 = JZ4740_GPIO_TRIG;
                reg2 = JZ4740_GPIO_DIR;
@@ -1758,8 +1758,8 @@ static void ingenic_gpio_irq_enable(struct irq_data *irqd)
        struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
        int irq = irqd->hwirq;
 
-       if (jzgc->jzpc->info->version >= ID_JZ4760)
-               ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true);
+       if (jzgc->jzpc->info->version >= ID_JZ4770)
+               ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
        else
                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
 
@@ -1774,8 +1774,8 @@ static void ingenic_gpio_irq_disable(struct irq_data *irqd)
 
        ingenic_gpio_irq_mask(irqd);
 
-       if (jzgc->jzpc->info->version >= ID_JZ4760)
-               ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false);
+       if (jzgc->jzpc->info->version >= ID_JZ4770)
+               ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
        else
                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
 }
@@ -1799,8 +1799,8 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd)
                        irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH);
        }
 
-       if (jzgc->jzpc->info->version >= ID_JZ4760)
-               ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false);
+       if (jzgc->jzpc->info->version >= ID_JZ4770)
+               ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
        else
                ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
 }
@@ -1856,8 +1856,8 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc)
 
        chained_irq_enter(irq_chip, desc);
 
-       if (jzgc->jzpc->info->version >= ID_JZ4760)
-               flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG);
+       if (jzgc->jzpc->info->version >= ID_JZ4770)
+               flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG);
        else
                flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
 
@@ -1938,9 +1938,9 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
        struct ingenic_pinctrl *jzpc = jzgc->jzpc;
        unsigned int pin = gc->base + offset;
 
-       if (jzpc->info->version >= ID_JZ4760) {
-               if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) ||
-                   ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1))
+       if (jzpc->info->version >= ID_JZ4770) {
+               if (ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_INT) ||
+                   ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1))
                        return GPIO_LINE_DIRECTION_IN;
                return GPIO_LINE_DIRECTION_OUT;
        }
@@ -1991,20 +1991,20 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
                        'A' + offt, idx, func);
 
        if (jzpc->info->version >= ID_X1000) {
-               ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+               ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
                ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, false);
-               ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
-               ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
+               ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
+               ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
                ingenic_shadow_config_pin_load(jzpc, pin);
-       } else if (jzpc->info->version >= ID_JZ4760) {
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+       } else if (jzpc->info->version >= ID_JZ4770) {
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
                ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
        } else {
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
-               ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
+               ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1);
        }
 
        return 0;
@@ -2057,14 +2057,14 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
                        'A' + offt, idx, input ? "in" : "out");
 
        if (jzpc->info->version >= ID_X1000) {
-               ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+               ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
                ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true);
-               ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
+               ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
                ingenic_shadow_config_pin_load(jzpc, pin);
-       } else if (jzpc->info->version >= ID_JZ4760) {
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
+       } else if (jzpc->info->version >= ID_JZ4770) {
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
                ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
        } else {
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
@@ -2091,8 +2091,8 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
        unsigned int offt = pin / PINS_PER_GPIO_CHIP;
        bool pull;
 
-       if (jzpc->info->version >= ID_JZ4760)
-               pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN);
+       if (jzpc->info->version >= ID_JZ4770)
+               pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
        else
                pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
 
@@ -2141,8 +2141,8 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
                                        REG_SET(X1830_GPIO_PEH), bias << idxh);
                }
 
-       } else if (jzpc->info->version >= ID_JZ4760) {
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !bias);
+       } else if (jzpc->info->version >= ID_JZ4770) {
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias);
        } else {
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias);
        }
@@ -2151,8 +2151,8 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
 static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc,
                                     unsigned int pin, bool high)
 {
-       if (jzpc->info->version >= ID_JZ4760)
-               ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high);
+       if (jzpc->info->version >= ID_JZ4770)
+               ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, high);
        else
                ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
 }
index e051aec..d70caec 100644 (file)
@@ -51,6 +51,7 @@
  * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
  *                  detection.
  * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
+ * @disabled_for_mux: These IRQs were disabled because we muxed away.
  * @soc:            Reference to soc_data of platform specific data.
  * @regs:           Base addresses for the TLMM tiles.
  * @phys_base:      Physical base address
@@ -72,6 +73,7 @@ struct msm_pinctrl {
        DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
        DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
        DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
+       DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
 
        const struct msm_pinctrl_soc_data *soc;
        void __iomem *regs[MAX_NR_TILES];
@@ -96,6 +98,14 @@ MSM_ACCESSOR(intr_cfg)
 MSM_ACCESSOR(intr_status)
 MSM_ACCESSOR(intr_target)
 
+static void msm_ack_intr_status(struct msm_pinctrl *pctrl,
+                               const struct msm_pingroup *g)
+{
+       u32 val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0;
+
+       msm_writel_intr_status(val, pctrl, g);
+}
+
 static int msm_get_groups_count(struct pinctrl_dev *pctldev)
 {
        struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -171,6 +181,10 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
                              unsigned group)
 {
        struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
+       struct gpio_chip *gc = &pctrl->chip;
+       unsigned int irq = irq_find_mapping(gc->irq.domain, group);
+       struct irq_data *d = irq_get_irq_data(irq);
+       unsigned int gpio_func = pctrl->soc->gpio_func;
        const struct msm_pingroup *g;
        unsigned long flags;
        u32 val, mask;
@@ -187,6 +201,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
        if (WARN_ON(i == g->nfuncs))
                return -EINVAL;
 
+       /*
+        * If an GPIO interrupt is setup on this pin then we need special
+        * handling.  Specifically interrupt detection logic will still see
+        * the pin twiddle even when we're muxed away.
+        *
+        * When we see a pin with an interrupt setup on it then we'll disable
+        * (mask) interrupts on it when we mux away until we mux back.  Note
+        * that disable_irq() refcounts and interrupts are disabled as long as
+        * at least one disable_irq() has been called.
+        */
+       if (d && i != gpio_func &&
+           !test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
+               disable_irq(irq);
+
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
        val = msm_readl_ctl(pctrl, g);
@@ -196,6 +224,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
 
        raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 
+       if (d && i == gpio_func &&
+           test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) {
+               /*
+                * Clear interrupts detected while not GPIO since we only
+                * masked things.
+                */
+               if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
+                       irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false);
+               else
+                       msm_ack_intr_status(pctrl, g);
+
+               enable_irq(irq);
+       }
+
        return 0;
 }
 
@@ -210,8 +252,7 @@ static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev,
        if (!g->nfuncs)
                return 0;
 
-       /* For now assume function 0 is GPIO because it always is */
-       return msm_pinmux_set_mux(pctldev, g->funcs[0], offset);
+       return msm_pinmux_set_mux(pctldev, g->funcs[pctrl->soc->gpio_func], offset);
 }
 
 static const struct pinmux_ops msm_pinmux_ops = {
@@ -774,7 +815,7 @@ static void msm_gpio_irq_mask(struct irq_data *d)
        raw_spin_unlock_irqrestore(&pctrl->lock, flags);
 }
 
-static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
+static void msm_gpio_irq_unmask(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
@@ -792,17 +833,6 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
 
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
-       if (status_clear) {
-               /*
-                * clear the interrupt status bit before unmask to avoid
-                * any erroneous interrupts that would have got latched
-                * when the interrupt is not in use.
-                */
-               val = msm_readl_intr_status(pctrl, g);
-               val &= ~BIT(g->intr_status_bit);
-               msm_writel_intr_status(val, pctrl, g);
-       }
-
        val = msm_readl_intr_cfg(pctrl, g);
        val |= BIT(g->intr_raw_status_bit);
        val |= BIT(g->intr_enable_bit);
@@ -822,7 +852,7 @@ static void msm_gpio_irq_enable(struct irq_data *d)
                irq_chip_enable_parent(d);
 
        if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
-               msm_gpio_irq_clear_unmask(d, true);
+               msm_gpio_irq_unmask(d);
 }
 
 static void msm_gpio_irq_disable(struct irq_data *d)
@@ -837,11 +867,6 @@ static void msm_gpio_irq_disable(struct irq_data *d)
                msm_gpio_irq_mask(d);
 }
 
-static void msm_gpio_irq_unmask(struct irq_data *d)
-{
-       msm_gpio_irq_clear_unmask(d, false);
-}
-
 /**
  * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent.
  * @d: The irq dta.
@@ -894,7 +919,6 @@ static void msm_gpio_irq_ack(struct irq_data *d)
        struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
        const struct msm_pingroup *g;
        unsigned long flags;
-       u32 val;
 
        if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) {
                if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
@@ -906,12 +930,7 @@ static void msm_gpio_irq_ack(struct irq_data *d)
 
        raw_spin_lock_irqsave(&pctrl->lock, flags);
 
-       val = msm_readl_intr_status(pctrl, g);
-       if (g->intr_ack_high)
-               val |= BIT(g->intr_status_bit);
-       else
-               val &= ~BIT(g->intr_status_bit);
-       msm_writel_intr_status(val, pctrl, g);
+       msm_ack_intr_status(pctrl, g);
 
        if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
                msm_gpio_update_dual_edge_pos(pctrl, g, d);
@@ -936,6 +955,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
        const struct msm_pingroup *g;
        unsigned long flags;
+       bool was_enabled;
        u32 val;
 
        if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) {
@@ -997,6 +1017,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
         * could cause the INTR_STATUS to be set for EDGE interrupts.
         */
        val = msm_readl_intr_cfg(pctrl, g);
+       was_enabled = val & BIT(g->intr_raw_status_bit);
        val |= BIT(g->intr_raw_status_bit);
        if (g->intr_detection_width == 2) {
                val &= ~(3 << g->intr_detection_bit);
@@ -1046,6 +1067,14 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        }
        msm_writel_intr_cfg(val, pctrl, g);
 
+       /*
+        * The first time we set RAW_STATUS_EN it could trigger an interrupt.
+        * Clear the interrupt.  This is safe because we have
+        * IRQCHIP_SET_TYPE_MASKED.
+        */
+       if (!was_enabled)
+               msm_ack_intr_status(pctrl, g);
+
        if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
                msm_gpio_update_dual_edge_pos(pctrl, g, d);
 
@@ -1099,16 +1128,11 @@ static int msm_gpio_irq_reqres(struct irq_data *d)
        }
 
        /*
-        * Clear the interrupt that may be pending before we enable
-        * the line.
-        * This is especially a problem with the GPIOs routed to the
-        * PDC. These GPIOs are direct-connect interrupts to the GIC.
-        * Disabling the interrupt line at the PDC does not prevent
-        * the interrupt from being latched at the GIC. The state at
-        * GIC needs to be cleared before enabling.
+        * The disable / clear-enable workaround we do in msm_pinmux_set_mux()
+        * only works if disable is not lazy since we only clear any bogus
+        * interrupt in hardware. Explicitly mark the interrupt as UNLAZY.
         */
-       if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
-               irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0);
+       irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
 
        return 0;
 out:
index 333f992..e31a516 100644 (file)
@@ -118,6 +118,7 @@ struct msm_gpio_wakeirq_map {
  * @wakeirq_dual_edge_errata: If true then GPIOs using the wakeirq_map need
  *                            to be aware that their parent can't handle dual
  *                            edge interrupts.
+ * @gpio_func: Which function number is GPIO (usually 0).
  */
 struct msm_pinctrl_soc_data {
        const struct pinctrl_pin_desc *pins;
@@ -134,6 +135,7 @@ struct msm_pinctrl_soc_data {
        const struct msm_gpio_wakeirq_map *wakeirq_map;
        unsigned int nwakeirq_map;
        bool wakeirq_dual_edge_errata;
+       unsigned int gpio_func;
 };
 
 extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;
index 33040b0..2c941cd 100644 (file)
@@ -5,6 +5,7 @@
 
 menuconfig SURFACE_PLATFORMS
        bool "Microsoft Surface Platform-Specific Device Drivers"
+       depends on ACPI
        default y
        help
          Say Y here to get to see options for platform-specific device drivers
@@ -29,20 +30,19 @@ config SURFACE3_WMI
 
 config SURFACE_3_BUTTON
        tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet"
-       depends on ACPI && KEYBOARD_GPIO && I2C
+       depends on KEYBOARD_GPIO && I2C
        help
          This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
 
 config SURFACE_3_POWER_OPREGION
        tristate "Surface 3 battery platform operation region support"
-       depends on ACPI && I2C
+       depends on I2C
        help
          This driver provides support for ACPI operation
          region of the Surface 3 battery platform driver.
 
 config SURFACE_GPE
        tristate "Surface GPE/Lid Support Driver"
-       depends on ACPI
        depends on DMI
        help
          This driver marks the GPEs related to the ACPI lid device found on
@@ -52,7 +52,7 @@ config SURFACE_GPE
 
 config SURFACE_PRO3_BUTTON
        tristate "Power/home/volume buttons driver for Microsoft Surface Pro 3/4 tablet"
-       depends on ACPI && INPUT
+       depends on INPUT
        help
          This driver handles the power/home/volume buttons on the Microsoft Surface Pro 3/4 tablet.
 
index e49e5d6..86f6991 100644 (file)
@@ -181,12 +181,12 @@ static int surface_lid_enable_wakeup(struct device *dev, bool enable)
        return 0;
 }
 
-static int surface_gpe_suspend(struct device *dev)
+static int __maybe_unused surface_gpe_suspend(struct device *dev)
 {
        return surface_lid_enable_wakeup(dev, true);
 }
 
-static int surface_gpe_resume(struct device *dev)
+static int __maybe_unused surface_gpe_resume(struct device *dev)
 {
        return surface_lid_enable_wakeup(dev, false);
 }
index 0102bf1..ef83425 100644 (file)
@@ -85,7 +85,7 @@ static inline void amd_pmc_reg_write(struct amd_pmc_dev *dev, int reg_offset, u3
        iowrite32(val, dev->regbase + reg_offset);
 }
 
-#if CONFIG_DEBUG_FS
+#ifdef CONFIG_DEBUG_FS
 static int smu_fw_info_show(struct seq_file *s, void *unused)
 {
        struct amd_pmc_dev *dev = s->private;
index ecd4779..18bf8ae 100644 (file)
@@ -247,7 +247,8 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
        ret = bios_return->return_code;
 
        if (ret) {
-               if (ret != HPWMI_RET_UNKNOWN_CMDTYPE)
+               if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
+                   ret != HPWMI_RET_UNKNOWN_CMDTYPE)
                        pr_warn("query 0x%x returned error 0x%x\n", query, ret);
                goto out_free;
        }
index b457b0b..2cce825 100644 (file)
@@ -164,13 +164,29 @@ static const struct i2c_inst_data bsg2150_data[]  = {
        {}
 };
 
-static const struct i2c_inst_data int3515_data[]  = {
-       { "tps6598x", IRQ_RESOURCE_APIC, 0 },
-       { "tps6598x", IRQ_RESOURCE_APIC, 1 },
-       { "tps6598x", IRQ_RESOURCE_APIC, 2 },
-       { "tps6598x", IRQ_RESOURCE_APIC, 3 },
-       {}
-};
+/*
+ * Device with _HID INT3515 (TI PD controllers) has some unresolved interrupt
+ * issues. The most common problem seen is interrupt flood.
+ *
+ * There are at least two known causes. Firstly, on some boards, the
+ * I2CSerialBus resource index does not match the Interrupt resource, i.e. they
+ * are not one-to-one mapped like in the array below. Secondly, on some boards
+ * the IRQ line from the PD controller is not actually connected at all. But the
+ * interrupt flood is also seen on some boards where those are not a problem, so
+ * there are some other problems as well.
+ *
+ * Because of the issues with the interrupt, the device is disabled for now. If
+ * you wish to debug the issues, uncomment the below, and add an entry for the
+ * INT3515 device to the i2c_multi_instance_ids table.
+ *
+ * static const struct i2c_inst_data int3515_data[]  = {
+ *     { "tps6598x", IRQ_RESOURCE_APIC, 0 },
+ *     { "tps6598x", IRQ_RESOURCE_APIC, 1 },
+ *     { "tps6598x", IRQ_RESOURCE_APIC, 2 },
+ *     { "tps6598x", IRQ_RESOURCE_APIC, 3 },
+ *     { }
+ * };
+ */
 
 /*
  * Note new device-ids must also be added to i2c_multi_instantiate_ids in
@@ -179,7 +195,6 @@ static const struct i2c_inst_data int3515_data[]  = {
 static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = {
        { "BSG1160", (unsigned long)bsg1160_data },
        { "BSG2150", (unsigned long)bsg2150_data },
-       { "INT3515", (unsigned long)int3515_data },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids);
index 7598cd4..5b81baf 100644 (file)
@@ -92,6 +92,7 @@ struct ideapad_private {
        struct dentry *debug;
        unsigned long cfg;
        bool has_hw_rfkill_switch;
+       bool has_touchpad_switch;
        const char *fnesc_guid;
 };
 
@@ -535,7 +536,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
        } else if (attr == &dev_attr_fn_lock.attr) {
                supported = acpi_has_method(priv->adev->handle, "HALS") &&
                        acpi_has_method(priv->adev->handle, "SALS");
-       } else
+       } else if (attr == &dev_attr_touchpad.attr)
+               supported = priv->has_touchpad_switch;
+       else
                supported = true;
 
        return supported ? attr->mode : 0;
@@ -867,6 +870,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv)
 {
        unsigned long value;
 
+       if (!priv->has_touchpad_switch)
+               return;
+
        /* Without reading from EC touchpad LED doesn't switch state */
        if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) {
                /* Some IdeaPads don't really turn off touchpad - they only
@@ -989,6 +995,9 @@ static int ideapad_acpi_add(struct platform_device *pdev)
        priv->platform_device = pdev;
        priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
 
+       /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
+       priv->has_touchpad_switch = !acpi_dev_present("ELAN0634", NULL, -1);
+
        ret = ideapad_sysfs_init(priv);
        if (ret)
                return ret;
@@ -1006,6 +1015,10 @@ static int ideapad_acpi_add(struct platform_device *pdev)
        if (!priv->has_hw_rfkill_switch)
                write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1);
 
+       /* The same for Touchpad */
+       if (!priv->has_touchpad_switch)
+               write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1);
+
        for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++)
                if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg))
                        ideapad_register_rfkill(priv, i);
index 3b49a1f..30a9062 100644 (file)
@@ -207,19 +207,19 @@ static const struct dmi_system_id dmi_switches_allow_list[] = {
        {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Stream x360 Convertible PC 11"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"),
                },
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"),
                },
        },
        {
                .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"),
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7352"),
                },
        },
        {} /* Array terminator */
index e03df28..f3e8eca 100644 (file)
@@ -8783,6 +8783,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
        TPACPI_Q_LNV3('N', '1', 'T', TPACPI_FAN_2CTL),  /* P71 */
        TPACPI_Q_LNV3('N', '1', 'U', TPACPI_FAN_2CTL),  /* P51 */
        TPACPI_Q_LNV3('N', '2', 'C', TPACPI_FAN_2CTL),  /* P52 / P72 */
+       TPACPI_Q_LNV3('N', '2', 'N', TPACPI_FAN_2CTL),  /* P53 / P73 */
        TPACPI_Q_LNV3('N', '2', 'E', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (1st gen) */
        TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (2nd gen) */
        TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL),  /* P1 / X1 Extreme (3nd gen) */
@@ -9951,9 +9952,9 @@ static int tpacpi_proxsensor_init(struct ibm_init_struct *iibm)
        if ((palm_err == -ENODEV) && (lap_err == -ENODEV))
                return 0;
        /* Otherwise, if there was an error return it */
-       if (palm_err && (palm_err != ENODEV))
+       if (palm_err && (palm_err != -ENODEV))
                return palm_err;
-       if (lap_err && (lap_err != ENODEV))
+       if (lap_err && (lap_err != -ENODEV))
                return lap_err;
 
        if (has_palmsensor) {
index 5783139..c4de932 100644 (file)
@@ -263,6 +263,16 @@ static const struct ts_dmi_data digma_citi_e200_data = {
        .properties     = digma_citi_e200_props,
 };
 
+static const struct property_entry estar_beauty_hd_props[] = {
+       PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+       { }
+};
+
+static const struct ts_dmi_data estar_beauty_hd_data = {
+       .acpi_name      = "GDIX1001:00",
+       .properties     = estar_beauty_hd_props,
+};
+
 static const struct property_entry gp_electronic_t701_props[] = {
        PROPERTY_ENTRY_U32("touchscreen-size-x", 960),
        PROPERTY_ENTRY_U32("touchscreen-size-y", 640),
@@ -942,6 +952,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
                },
        },
+       {
+               /* Estar Beauty HD (MID 7316R) */
+               .driver_data = (void *)&estar_beauty_hd_data,
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Estar"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"),
+               },
+       },
        {
                /* GP-electronic T701 */
                .driver_data = (void *)&gp_electronic_t701_data,
index a2beee6..5988c30 100644 (file)
@@ -444,7 +444,8 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev)
        fetch_index = ioread32(&vdev->devcmd2->wq.ctrl->fetch_index);
        if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */
                pr_err("error in devcmd2 init");
-               return -ENODEV;
+               err = -ENODEV;
+               goto err_free_wq;
        }
 
        /*
@@ -460,7 +461,7 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev)
        err = vnic_dev_alloc_desc_ring(vdev, &vdev->devcmd2->results_ring,
                        DEVCMD2_RING_SIZE, DEVCMD2_DESC_SIZE);
        if (err)
-               goto err_free_wq;
+               goto err_disable_wq;
 
        vdev->devcmd2->result =
                (struct devcmd2_result *) vdev->devcmd2->results_ring.descs;
@@ -481,8 +482,9 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev)
 
 err_free_desc_ring:
        vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring);
-err_free_wq:
+err_disable_wq:
        vnic_wq_disable(&vdev->devcmd2->wq);
+err_free_wq:
        vnic_wq_free(&vdev->devcmd2->wq);
 err_free_devcmd2:
        kfree(vdev->devcmd2);
index 42e4d35..65f168c 100644 (file)
@@ -1744,7 +1744,7 @@ static int ibmvfc_queuecommand_lck(struct scsi_cmnd *cmnd,
                iu->pri_task_attr = IBMVFC_SIMPLE_TASK;
        }
 
-       vfc_cmd->correlation = cpu_to_be64(evt);
+       vfc_cmd->correlation = cpu_to_be64((u64)evt);
 
        if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev))))
                return ibmvfc_send_event(evt, vhost, 0);
@@ -2418,7 +2418,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev)
                tmf->flags = cpu_to_be16((IBMVFC_NO_MEM_DESC | IBMVFC_TMF));
                evt->sync_iu = &rsp_iu;
 
-               tmf->correlation = cpu_to_be64(evt);
+               tmf->correlation = cpu_to_be64((u64)evt);
 
                init_completion(&evt->comp);
                rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
@@ -3007,8 +3007,10 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev)
        unsigned long flags = 0;
 
        spin_lock_irqsave(shost->host_lock, flags);
-       if (sdev->type == TYPE_DISK)
+       if (sdev->type == TYPE_DISK) {
                sdev->allow_restart = 1;
+               blk_queue_rq_timeout(sdev->request_queue, 120 * HZ);
+       }
        spin_unlock_irqrestore(shost->host_lock, flags);
        return 0;
 }
index d71afae..8410004 100644 (file)
@@ -1623,8 +1623,13 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
                rc = fc_exch_done_locked(ep);
                WARN_ON(fc_seq_exch(sp) != ep);
                spin_unlock_bh(&ep->ex_lock);
-               if (!rc)
+               if (!rc) {
                        fc_exch_delete(ep);
+               } else {
+                       FC_EXCH_DBG(ep, "ep is completed already,"
+                                       "hence skip calling the resp\n");
+                       goto skip_resp;
+               }
        }
 
        /*
@@ -1643,6 +1648,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
        if (!fc_invoke_resp(ep, sp, fp))
                fc_frame_free(fp);
 
+skip_resp:
        fc_exch_release(ep);
        return;
 rel:
@@ -1899,10 +1905,16 @@ static void fc_exch_reset(struct fc_exch *ep)
 
        fc_exch_hold(ep);
 
-       if (!rc)
+       if (!rc) {
                fc_exch_delete(ep);
+       } else {
+               FC_EXCH_DBG(ep, "ep is completed already,"
+                               "hence skip calling the resp\n");
+               goto skip_resp;
+       }
 
        fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED));
+skip_resp:
        fc_seq_set_resp(sp, NULL, ep->arg);
        fc_exch_release(ep);
 }
index af19209..63a4f48 100644 (file)
@@ -8244,11 +8244,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
                        goto out;
                }
 
+               /* always store 64 bits regardless of addressing */
                sense_ptr = (void *)cmd->frame + ioc->sense_off;
-               if (instance->consistent_mask_64bit)
-                       put_unaligned_le64(sense_handle, sense_ptr);
-               else
-                       put_unaligned_le32(sense_handle, sense_ptr);
+               put_unaligned_le64(sense_handle, sense_ptr);
        }
 
        /*
index cba1cf6..1e939a2 100644 (file)
@@ -541,7 +541,14 @@ int srp_reconnect_rport(struct srp_rport *rport)
        res = mutex_lock_interruptible(&rport->mutex);
        if (res)
                goto out;
-       scsi_target_block(&shost->shost_gendev);
+       if (rport->state != SRP_RPORT_FAIL_FAST)
+               /*
+                * sdev state must be SDEV_TRANSPORT_OFFLINE, transition
+                * to SDEV_BLOCK is illegal. Calling scsi_target_unblock()
+                * later is ok though, scsi_internal_device_unblock_nowait()
+                * treats SDEV_TRANSPORT_OFFLINE like SDEV_BLOCK.
+                */
+               scsi_target_block(&shost->shost_gendev);
        res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV;
        pr_debug("%s (state %d): transport.reconnect() returned %d\n",
                 dev_name(&shost->shost_gendev), rport->state, res);
index 3f6dfed..b915b38 100644 (file)
@@ -72,6 +72,7 @@ config SCSI_UFS_DWC_TC_PCI
 config SCSI_UFSHCD_PLATFORM
        tristate "Platform bus based UFS Controller support"
        depends on SCSI_UFSHCD
+       depends on HAS_IOMEM
        help
        This selects the UFS host controller support. Select this if
        you have an UFS controller on Platform bus.
index e31d2c5..fb32d12 100644 (file)
@@ -3996,6 +3996,8 @@ int ufshcd_link_recovery(struct ufs_hba *hba)
        if (ret)
                dev_err(hba->dev, "%s: link recovery failed, err %d",
                        __func__, ret);
+       else
+               ufshcd_clear_ua_wluns(hba);
 
        return ret;
 }
@@ -4992,7 +4994,8 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
                break;
        } /* end of switch */
 
-       if ((host_byte(result) != DID_OK) && !hba->silence_err_logs)
+       if ((host_byte(result) != DID_OK) &&
+           (host_byte(result) != DID_REQUEUE) && !hba->silence_err_logs)
                ufshcd_print_trs(hba, 1 << lrbp->task_tag, true);
        return result;
 }
@@ -6001,6 +6004,9 @@ skip_err_handling:
        ufshcd_scsi_unblock_requests(hba);
        ufshcd_err_handling_unprepare(hba);
        up(&hba->eh_sem);
+
+       if (!err && needs_reset)
+               ufshcd_clear_ua_wluns(hba);
 }
 
 /**
@@ -6295,9 +6301,13 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
                intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
        }
 
-       if (enabled_intr_status && retval == IRQ_NONE) {
-               dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n",
-                                       __func__, intr_status);
+       if (enabled_intr_status && retval == IRQ_NONE &&
+                               !ufshcd_eh_in_progress(hba)) {
+               dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x (0x%08x, 0x%08x)\n",
+                                       __func__,
+                                       intr_status,
+                                       hba->ufs_stats.last_intr_status,
+                                       enabled_intr_status);
                ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: ");
        }
 
@@ -6341,7 +6351,10 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
         * Even though we use wait_event() which sleeps indefinitely,
         * the maximum wait time is bounded by %TM_CMD_TIMEOUT.
         */
-       req = blk_get_request(q, REQ_OP_DRV_OUT, BLK_MQ_REQ_RESERVED);
+       req = blk_get_request(q, REQ_OP_DRV_OUT, 0);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
        req->end_io_data = &wait;
        free_slot = req->tag;
        WARN_ON_ONCE(free_slot < 0 || free_slot >= hba->nutmrs);
@@ -6938,14 +6951,11 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
        ufshcd_set_clk_freq(hba, true);
 
        err = ufshcd_hba_enable(hba);
-       if (err)
-               goto out;
 
        /* Establish the link again and restore the device */
-       err = ufshcd_probe_hba(hba, false);
        if (!err)
-               ufshcd_clear_ua_wluns(hba);
-out:
+               err = ufshcd_probe_hba(hba, false);
+
        if (err)
                dev_err(hba->dev, "%s: Host init failed %d\n", __func__, err);
        ufshcd_update_evt_hist(hba, UFS_EVT_HOST_RESET, (u32)err);
@@ -7716,6 +7726,8 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
        if (ret)
                goto out;
 
+       ufshcd_clear_ua_wluns(hba);
+
        /* Initialize devfreq after UFS device is detected */
        if (ufshcd_is_clkscaling_supported(hba)) {
                memcpy(&hba->clk_scaling.saved_pwr_info.info,
@@ -7917,8 +7929,6 @@ out:
                pm_runtime_put_sync(hba->dev);
                ufshcd_exit_clk_scaling(hba);
                ufshcd_hba_exit(hba);
-       } else {
-               ufshcd_clear_ua_wluns(hba);
        }
 }
 
@@ -8775,6 +8785,7 @@ enable_gating:
                ufshcd_resume_clkscaling(hba);
        hba->clk_gating.is_suspended = false;
        hba->dev_info.b_rpm_dev_flush_capable = false;
+       ufshcd_clear_ua_wluns(hba);
        ufshcd_release(hba);
 out:
        if (hba->dev_info.b_rpm_dev_flush_capable) {
@@ -8885,6 +8896,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
                cancel_delayed_work(&hba->rpm_dev_flush_recheck_work);
        }
 
+       ufshcd_clear_ua_wluns(hba);
+
        /* Schedule clock gating in case of no access to UFS device yet */
        ufshcd_release(hba);
 
index 1217caf..9b07663 100644 (file)
@@ -140,12 +140,13 @@ struct litex_soc_ctrl_device {
        void __iomem *base;
 };
 
+#ifdef CONFIG_OF
 static const struct of_device_id litex_soc_ctrl_of_match[] = {
        {.compatible = "litex,soc-controller"},
        {},
 };
-
 MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match);
+#endif /* CONFIG_OF */
 
 static int litex_soc_ctrl_probe(struct platform_device *pdev)
 {
index 70467b9..a3afd1b 100644 (file)
@@ -115,6 +115,7 @@ struct cdns_spi {
        void __iomem *regs;
        struct clk *ref_clk;
        struct clk *pclk;
+       unsigned int clk_rate;
        u32 speed_hz;
        const u8 *txbuf;
        u8 *rxbuf;
@@ -250,7 +251,7 @@ static void cdns_spi_config_clock_freq(struct spi_device *spi,
        u32 ctrl_reg, baud_rate_val;
        unsigned long frequency;
 
-       frequency = clk_get_rate(xspi->ref_clk);
+       frequency = xspi->clk_rate;
 
        ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
 
@@ -558,8 +559,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
        master->auto_runtime_pm = true;
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
+       xspi->clk_rate = clk_get_rate(xspi->ref_clk);
        /* Set to default valid value */
-       master->max_speed_hz = clk_get_rate(xspi->ref_clk) / 4;
+       master->max_speed_hz = xspi->clk_rate / 4;
        xspi->speed_hz = master->max_speed_hz;
 
        master->bits_per_word_mask = SPI_BPW_MASK(8);
index 9494257..6d8e0a0 100644 (file)
@@ -115,14 +115,13 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value)
 {
        struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
        struct fsl_spi_platform_data *pdata;
-       bool pol = spi->mode & SPI_CS_HIGH;
        struct spi_mpc8xxx_cs   *cs = spi->controller_state;
 
        pdata = spi->dev.parent->parent->platform_data;
 
        if (value == BITBANG_CS_INACTIVE) {
                if (pdata->cs_control)
-                       pdata->cs_control(spi, !pol);
+                       pdata->cs_control(spi, false);
        }
 
        if (value == BITBANG_CS_ACTIVE) {
@@ -134,7 +133,7 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value)
                fsl_spi_change_mode(spi);
 
                if (pdata->cs_control)
-                       pdata->cs_control(spi, pol);
+                       pdata->cs_control(spi, true);
        }
 }
 
index 6b171ff..a5991df 100644 (file)
@@ -562,8 +562,6 @@ tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dbi)
 
 static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd)
 {
-       if (tcmu_cmd->se_cmd)
-               tcmu_cmd->se_cmd->priv = NULL;
        kfree(tcmu_cmd->dbi);
        kmem_cache_free(tcmu_cmd_cache, tcmu_cmd);
 }
@@ -1174,11 +1172,12 @@ tcmu_queue_cmd(struct se_cmd *se_cmd)
                return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
        mutex_lock(&udev->cmdr_lock);
-       se_cmd->priv = tcmu_cmd;
        if (!(se_cmd->transport_state & CMD_T_ABORTED))
                ret = queue_cmd_ring(tcmu_cmd, &scsi_ret);
        if (ret < 0)
                tcmu_free_cmd(tcmu_cmd);
+       else
+               se_cmd->priv = tcmu_cmd;
        mutex_unlock(&udev->cmdr_lock);
        return scsi_ret;
 }
@@ -1241,6 +1240,7 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf,
 
                list_del_init(&cmd->queue_entry);
                tcmu_free_cmd(cmd);
+               se_cmd->priv = NULL;
                target_complete_cmd(se_cmd, SAM_STAT_TASK_ABORTED);
                unqueued = true;
        }
@@ -1332,6 +1332,7 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
        }
 
 done:
+       se_cmd->priv = NULL;
        if (read_len_valid) {
                pr_debug("read_len = %d\n", read_len);
                target_complete_cmd_with_length(cmd->se_cmd,
@@ -1478,6 +1479,7 @@ static void tcmu_check_expired_queue_cmd(struct tcmu_cmd *cmd)
        se_cmd = cmd->se_cmd;
        tcmu_free_cmd(cmd);
 
+       se_cmd->priv = NULL;
        target_complete_cmd(se_cmd, SAM_STAT_TASK_SET_FULL);
 }
 
@@ -1592,6 +1594,7 @@ static void run_qfull_queue(struct tcmu_dev *udev, bool fail)
                         * removed then LIO core will do the right thing and
                         * fail the retry.
                         */
+                       tcmu_cmd->se_cmd->priv = NULL;
                        target_complete_cmd(tcmu_cmd->se_cmd, SAM_STAT_BUSY);
                        tcmu_free_cmd(tcmu_cmd);
                        continue;
@@ -1605,6 +1608,7 @@ static void run_qfull_queue(struct tcmu_dev *udev, bool fail)
                         * Ignore scsi_ret for now. target_complete_cmd
                         * drops it.
                         */
+                       tcmu_cmd->se_cmd->priv = NULL;
                        target_complete_cmd(tcmu_cmd->se_cmd,
                                            SAM_STAT_CHECK_CONDITION);
                        tcmu_free_cmd(tcmu_cmd);
@@ -2212,6 +2216,7 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level)
                if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) {
                        WARN_ON(!cmd->se_cmd);
                        list_del_init(&cmd->queue_entry);
+                       cmd->se_cmd->priv = NULL;
                        if (err_level == 1) {
                                /*
                                 * Userspace was not able to start the
index 02d7d7b..9cadacf 100644 (file)
@@ -3117,7 +3117,7 @@ void btrfs_backref_error_cleanup(struct btrfs_backref_cache *cache,
                list_del_init(&lower->list);
                if (lower == node)
                        node = NULL;
-               btrfs_backref_free_node(cache, lower);
+               btrfs_backref_drop_node(cache, lower);
        }
 
        btrfs_backref_cleanup_node(cache, node);
index 52f2198..0886e81 100644 (file)
@@ -2669,7 +2669,8 @@ again:
         * Go through delayed refs for all the stuff we've just kicked off
         * and then loop back (just once)
         */
-       ret = btrfs_run_delayed_refs(trans, 0);
+       if (!ret)
+               ret = btrfs_run_delayed_refs(trans, 0);
        if (!ret && loops == 0) {
                loops++;
                spin_lock(&cur_trans->dirty_bgs_lock);
index d79b836..30b1a63 100644 (file)
@@ -5549,7 +5549,15 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
                                goto out_free;
                        }
 
-                       trans = btrfs_start_transaction(tree_root, 0);
+                      /*
+                       * Use join to avoid potential EINTR from transaction
+                       * start. See wait_reserve_ticket and the whole
+                       * reservation callchain.
+                       */
+                       if (for_reloc)
+                               trans = btrfs_join_transaction(tree_root);
+                       else
+                               trans = btrfs_start_transaction(tree_root, 0);
                        if (IS_ERR(trans)) {
                                err = PTR_ERR(trans);
                                goto out_free;
index ae97f4d..78a3537 100644 (file)
@@ -5512,6 +5512,21 @@ static int clone_range(struct send_ctx *sctx,
                        break;
                offset += clone_len;
                clone_root->offset += clone_len;
+
+               /*
+                * If we are cloning from the file we are currently processing,
+                * and using the send root as the clone root, we must stop once
+                * the current clone offset reaches the current eof of the file
+                * at the receiver, otherwise we would issue an invalid clone
+                * operation (source range going beyond eof) and cause the
+                * receiver to fail. So if we reach the current eof, bail out
+                * and fallback to a regular write.
+                */
+               if (clone_root->root == sctx->send_root &&
+                   clone_root->ino == sctx->cur_ino &&
+                   clone_root->offset >= sctx->cur_inode_next_write_offset)
+                       break;
+
                data_offset += clone_len;
 next:
                path->slots[0]++;
index 8e0f7a1..6af7f2b 100644 (file)
@@ -2264,14 +2264,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         */
        btrfs_free_log_root_tree(trans, fs_info);
 
-       /*
-        * commit_fs_roots() can call btrfs_save_ino_cache(), which generates
-        * new delayed refs. Must handle them or qgroup can be wrong.
-        */
-       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
-       if (ret)
-               goto unlock_tree_log;
-
        /*
         * Since fs roots are all committed, we can get a quite accurate
         * new_roots. So let's do quota accounting.
index b62be84..0a6de85 100644 (file)
@@ -4317,6 +4317,8 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
                btrfs_warn(fs_info,
        "balance: cannot set exclusive op status, resume manually");
 
+       btrfs_release_path(path);
+
        mutex_lock(&fs_info->balance_mutex);
        BUG_ON(fs_info->balance_ctl);
        spin_lock(&fs_info->balance_lock);
index 8bda092..e027c71 100644 (file)
@@ -413,7 +413,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
 
        inode = d_backing_inode(object->backer);
        ASSERT(S_ISREG(inode->i_mode));
-       ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
@@ -713,7 +712,6 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
 
        inode = d_backing_inode(object->backer);
        ASSERT(S_ISREG(inode->i_mode));
-       ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
index 8405870..d87bd85 100644 (file)
@@ -5038,7 +5038,7 @@ bad:
        return;
 }
 
-static struct ceph_connection *con_get(struct ceph_connection *con)
+static struct ceph_connection *mds_get_con(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
 
@@ -5047,7 +5047,7 @@ static struct ceph_connection *con_get(struct ceph_connection *con)
        return NULL;
 }
 
-static void con_put(struct ceph_connection *con)
+static void mds_put_con(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
 
@@ -5058,7 +5058,7 @@ static void con_put(struct ceph_connection *con)
  * if the client is unresponsive for long enough, the mds will kill
  * the session entirely.
  */
-static void peer_reset(struct ceph_connection *con)
+static void mds_peer_reset(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
        struct ceph_mds_client *mdsc = s->s_mdsc;
@@ -5067,7 +5067,7 @@ static void peer_reset(struct ceph_connection *con)
        send_mds_reconnect(mdsc, s);
 }
 
-static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+static void mds_dispatch(struct ceph_connection *con, struct ceph_msg *msg)
 {
        struct ceph_mds_session *s = con->private;
        struct ceph_mds_client *mdsc = s->s_mdsc;
@@ -5125,8 +5125,8 @@ out:
  * Note: returned pointer is the address of a structure that's
  * managed separately.  Caller must *not* attempt to free it.
  */
-static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
-                                       int *proto, int force_new)
+static struct ceph_auth_handshake *
+mds_get_authorizer(struct ceph_connection *con, int *proto, int force_new)
 {
        struct ceph_mds_session *s = con->private;
        struct ceph_mds_client *mdsc = s->s_mdsc;
@@ -5142,7 +5142,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
        return auth;
 }
 
-static int add_authorizer_challenge(struct ceph_connection *con,
+static int mds_add_authorizer_challenge(struct ceph_connection *con,
                                    void *challenge_buf, int challenge_buf_len)
 {
        struct ceph_mds_session *s = con->private;
@@ -5153,7 +5153,7 @@ static int add_authorizer_challenge(struct ceph_connection *con,
                                            challenge_buf, challenge_buf_len);
 }
 
-static int verify_authorizer_reply(struct ceph_connection *con)
+static int mds_verify_authorizer_reply(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
        struct ceph_mds_client *mdsc = s->s_mdsc;
@@ -5165,7 +5165,7 @@ static int verify_authorizer_reply(struct ceph_connection *con)
                NULL, NULL, NULL, NULL);
 }
 
-static int invalidate_authorizer(struct ceph_connection *con)
+static int mds_invalidate_authorizer(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
        struct ceph_mds_client *mdsc = s->s_mdsc;
@@ -5288,15 +5288,15 @@ static int mds_check_message_signature(struct ceph_msg *msg)
 }
 
 static const struct ceph_connection_operations mds_con_ops = {
-       .get = con_get,
-       .put = con_put,
-       .dispatch = dispatch,
-       .get_authorizer = get_authorizer,
-       .add_authorizer_challenge = add_authorizer_challenge,
-       .verify_authorizer_reply = verify_authorizer_reply,
-       .invalidate_authorizer = invalidate_authorizer,
-       .peer_reset = peer_reset,
+       .get = mds_get_con,
+       .put = mds_put_con,
        .alloc_msg = mds_alloc_msg,
+       .dispatch = mds_dispatch,
+       .peer_reset = mds_peer_reset,
+       .get_authorizer = mds_get_authorizer,
+       .add_authorizer_challenge = mds_add_authorizer_challenge,
+       .verify_authorizer_reply = mds_verify_authorizer_reply,
+       .invalidate_authorizer = mds_invalidate_authorizer,
        .sign_message = mds_sign_message,
        .check_message_signature = mds_check_message_signature,
        .get_auth_request = mds_get_auth_request,
index acfb558..c41cb88 100644 (file)
@@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        }
 
        /*
-        * Some filesystems may redirty the inode during the writeback
-        * due to delalloc, clear dirty metadata flags right before
-        * write_inode()
+        * If the inode has dirty timestamps and we need to write them, call
+        * mark_inode_dirty_sync() to notify the filesystem about it and to
+        * change I_DIRTY_TIME into I_DIRTY_SYNC.
         */
-       spin_lock(&inode->i_lock);
-
-       dirty = inode->i_state & I_DIRTY;
        if ((inode->i_state & I_DIRTY_TIME) &&
-           ((dirty & I_DIRTY_INODE) ||
-            wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+           (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
             time_after(jiffies, inode->dirtied_time_when +
                        dirtytime_expire_interval * HZ))) {
-               dirty |= I_DIRTY_TIME;
                trace_writeback_lazytime(inode);
+               mark_inode_dirty_sync(inode);
        }
+
+       /*
+        * Some filesystems may redirty the inode during the writeback
+        * due to delalloc, clear dirty metadata flags right before
+        * write_inode()
+        */
+       spin_lock(&inode->i_lock);
+       dirty = inode->i_state & I_DIRTY;
        inode->i_state &= ~dirty;
 
        /*
@@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 
        spin_unlock(&inode->i_lock);
 
-       if (dirty & I_DIRTY_TIME)
-               mark_inode_dirty_sync(inode);
        /* Don't write the inode if only I_DIRTY_PAGES was set */
        if (dirty & ~I_DIRTY_PAGES) {
                int err = write_inode(inode, wbc);
index 821db21..34b8802 100644 (file)
@@ -865,9 +865,14 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
        if (isdotent(name, namlen)) {
                if (namlen == 2) {
                        dchild = dget_parent(dparent);
-                       /* filesystem root - cannot return filehandle for ".." */
+                       /*
+                        * Don't return filehandle for ".." if we're at
+                        * the filesystem or export root:
+                        */
                        if (dchild == dparent)
                                goto out;
+                       if (dparent == exp->ex_path.dentry)
+                               goto out;
                } else
                        dchild = dget(dparent);
        } else
index 5bef3a6..d0df217 100644 (file)
@@ -705,6 +705,7 @@ static int udf_check_vsd(struct super_block *sb)
        struct buffer_head *bh = NULL;
        int nsr = 0;
        struct udf_sb_info *sbi;
+       loff_t session_offset;
 
        sbi = UDF_SB(sb);
        if (sb->s_blocksize < sizeof(struct volStructDesc))
@@ -712,7 +713,8 @@ static int udf_check_vsd(struct super_block *sb)
        else
                sectorsize = sb->s_blocksize;
 
-       sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits);
+       session_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits;
+       sector += session_offset;
 
        udf_debug("Starting at sector %u (%lu byte sectors)\n",
                  (unsigned int)(sector >> sb->s_blocksize_bits),
@@ -757,8 +759,7 @@ static int udf_check_vsd(struct super_block *sb)
 
        if (nsr > 0)
                return 1;
-       else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
-                       VSD_FIRST_SECTOR_OFFSET)
+       else if (!bh && sector - session_offset == VSD_FIRST_SECTOR_OFFSET)
                return -1;
        else
                return 0;
index 5d71e8a..aca4dc0 100644 (file)
@@ -35,6 +35,9 @@ struct mdiobb_ctrl {
        const struct mdiobb_ops *ops;
 };
 
+int mdiobb_read(struct mii_bus *bus, int phy, int reg);
+int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val);
+
 /* The returned bus is not yet registered with the phy layer. */
 struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl);
 
index 88a7673..cfbfd6f 100644 (file)
@@ -81,6 +81,8 @@ struct usbnet {
 #              define EVENT_LINK_CHANGE        11
 #              define EVENT_SET_RX_MODE        12
 #              define EVENT_NO_IP_ALIGN        13
+       u32                     rx_speed;       /* in bps - NOT Mbps */
+       u32                     tx_speed;       /* in bps - NOT Mbps */
 };
 
 static inline struct usb_driver *driver_of(struct usb_interface *intf)
index 9a4bbcc..0d6f7ec 100644 (file)
@@ -1756,7 +1756,7 @@ struct cfg80211_sar_specs {
 
 
 /**
- * @struct cfg80211_sar_chan_ranges - sar frequency ranges
+ * struct cfg80211_sar_freq_ranges - sar frequency ranges
  * @start_freq:  start range edge frequency
  * @end_freq:    end range edge frequency
  */
@@ -3972,6 +3972,8 @@ struct mgmt_frame_regs {
  *     This callback may sleep.
  * @reset_tid_config: Reset TID specific configuration for the peer, for the
  *     given TIDs. This callback may sleep.
+ *
+ * @set_sar_specs: Update the SAR (TX power) settings.
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -4929,6 +4931,7 @@ struct wiphy_iftype_akm_suites {
  * @max_data_retry_count: maximum supported per TID retry count for
  *     configuration through the %NL80211_TID_CONFIG_ATTR_RETRY_SHORT and
  *     %NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes
+ * @sar_capa: SAR control capabilities
  */
 struct wiphy {
        /* assign these fields before you register the wiphy */
index 7338b38..111d777 100644 (file)
@@ -76,6 +76,8 @@ struct inet_connection_sock_af_ops {
  * @icsk_ext_hdr_len:     Network protocol overhead (IP/IPv6 options)
  * @icsk_ack:             Delayed ACK control data
  * @icsk_mtup;            MTU probing control data
+ * @icsk_probes_tstamp:    Probe timestamp (cleared by non-zero window ack)
+ * @icsk_user_timeout:    TCP_USER_TIMEOUT value
  */
 struct inet_connection_sock {
        /* inet_sock has to be the first member! */
@@ -129,6 +131,7 @@ struct inet_connection_sock {
 
                u32               probe_timestamp;
        } icsk_mtup;
+       u32                       icsk_probes_tstamp;
        u32                       icsk_user_timeout;
 
        u64                       icsk_ca_priv[104 / sizeof(u64)];
index d315740..2bdbf62 100644 (file)
@@ -3880,6 +3880,7 @@ enum ieee80211_reconfig_type {
  *     This callback may sleep.
  * @sta_set_4addr: Called to notify the driver when a station starts/stops using
  *     4-address mode
+ * @set_sar_specs: Update the SAR (TX power) settings.
  */
 struct ieee80211_ops {
        void (*tx)(struct ieee80211_hw *hw,
index bdc4323..129d200 100644 (file)
@@ -1921,10 +1921,13 @@ static inline void sk_set_txhash(struct sock *sk)
        sk->sk_txhash = net_tx_rndhash();
 }
 
-static inline void sk_rethink_txhash(struct sock *sk)
+static inline bool sk_rethink_txhash(struct sock *sk)
 {
-       if (sk->sk_txhash)
+       if (sk->sk_txhash) {
                sk_set_txhash(sk);
+               return true;
+       }
+       return false;
 }
 
 static inline struct dst_entry *
@@ -1947,12 +1950,10 @@ sk_dst_get(struct sock *sk)
        return dst;
 }
 
-static inline void dst_negative_advice(struct sock *sk)
+static inline void __dst_negative_advice(struct sock *sk)
 {
        struct dst_entry *ndst, *dst = __sk_dst_get(sk);
 
-       sk_rethink_txhash(sk);
-
        if (dst && dst->ops->negative_advice) {
                ndst = dst->ops->negative_advice(dst);
 
@@ -1964,6 +1965,12 @@ static inline void dst_negative_advice(struct sock *sk)
        }
 }
 
+static inline void dst_negative_advice(struct sock *sk)
+{
+       sk_rethink_txhash(sk);
+       __dst_negative_advice(sk);
+}
+
 static inline void
 __sk_dst_set(struct sock *sk, struct dst_entry *dst)
 {
index 58994e0..6f89c27 100644 (file)
@@ -1424,13 +1424,61 @@ TRACE_EVENT(rpcb_unregister,
        )
 );
 
+/* Record an xdr_buf containing a fully-formed RPC message */
+DECLARE_EVENT_CLASS(svc_xdr_msg_class,
+       TP_PROTO(
+               const struct xdr_buf *xdr
+       ),
+
+       TP_ARGS(xdr),
+
+       TP_STRUCT__entry(
+               __field(u32, xid)
+               __field(const void *, head_base)
+               __field(size_t, head_len)
+               __field(const void *, tail_base)
+               __field(size_t, tail_len)
+               __field(unsigned int, page_len)
+               __field(unsigned int, msg_len)
+       ),
+
+       TP_fast_assign(
+               __be32 *p = (__be32 *)xdr->head[0].iov_base;
+
+               __entry->xid = be32_to_cpu(*p);
+               __entry->head_base = p;
+               __entry->head_len = xdr->head[0].iov_len;
+               __entry->tail_base = xdr->tail[0].iov_base;
+               __entry->tail_len = xdr->tail[0].iov_len;
+               __entry->page_len = xdr->page_len;
+               __entry->msg_len = xdr->len;
+       ),
+
+       TP_printk("xid=0x%08x head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
+               __entry->xid,
+               __entry->head_base, __entry->head_len, __entry->page_len,
+               __entry->tail_base, __entry->tail_len, __entry->msg_len
+       )
+);
+
+#define DEFINE_SVCXDRMSG_EVENT(name)                                   \
+               DEFINE_EVENT(svc_xdr_msg_class,                         \
+                               svc_xdr_##name,                         \
+                               TP_PROTO(                               \
+                                       const struct xdr_buf *xdr       \
+                               ),                                      \
+                               TP_ARGS(xdr))
+
+DEFINE_SVCXDRMSG_EVENT(recvfrom);
+
+/* Record an xdr_buf containing arbitrary data, tagged with an XID */
 DECLARE_EVENT_CLASS(svc_xdr_buf_class,
        TP_PROTO(
-               const struct svc_rqst *rqst,
+               __be32 xid,
                const struct xdr_buf *xdr
        ),
 
-       TP_ARGS(rqst, xdr),
+       TP_ARGS(xid, xdr),
 
        TP_STRUCT__entry(
                __field(u32, xid)
@@ -1443,7 +1491,7 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class,
        ),
 
        TP_fast_assign(
-               __entry->xid = be32_to_cpu(rqst->rq_xid);
+               __entry->xid = be32_to_cpu(xid);
                __entry->head_base = xdr->head[0].iov_base;
                __entry->head_len = xdr->head[0].iov_len;
                __entry->tail_base = xdr->tail[0].iov_base;
@@ -1463,12 +1511,11 @@ DECLARE_EVENT_CLASS(svc_xdr_buf_class,
                DEFINE_EVENT(svc_xdr_buf_class,                         \
                                svc_xdr_##name,                         \
                                TP_PROTO(                               \
-                                       const struct svc_rqst *rqst,    \
+                                       __be32 xid,                     \
                                        const struct xdr_buf *xdr       \
                                ),                                      \
-                               TP_ARGS(rqst, xdr))
+                               TP_ARGS(xid, xdr))
 
-DEFINE_SVCXDRBUF_EVENT(recvfrom);
 DEFINE_SVCXDRBUF_EVENT(sendto);
 
 /*
index 6edff97..2f05973 100644 (file)
@@ -176,14 +176,14 @@ BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode,
         * bpf_local_storage_update expects the owner to have a
         * valid storage pointer.
         */
-       if (!inode_storage_ptr(inode))
+       if (!inode || !inode_storage_ptr(inode))
                return (unsigned long)NULL;
 
        sdata = inode_storage_lookup(inode, map, true);
        if (sdata)
                return (unsigned long)sdata->data;
 
-       /* This helper must only called from where the inode is gurranteed
+       /* This helper must only called from where the inode is guaranteed
         * to have a refcount and cannot be freed.
         */
        if (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) {
@@ -200,7 +200,10 @@ BPF_CALL_4(bpf_inode_storage_get, struct bpf_map *, map, struct inode *, inode,
 BPF_CALL_2(bpf_inode_storage_delete,
           struct bpf_map *, map, struct inode *, inode)
 {
-       /* This helper must only called from where the inode is gurranteed
+       if (!inode)
+               return -EINVAL;
+
+       /* This helper must only called from where the inode is guaranteed
         * to have a refcount and cannot be freed.
         */
        return inode_storage_delete(inode, map);
index 4ef1959..e0da025 100644 (file)
@@ -218,7 +218,7 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,
         * bpf_local_storage_update expects the owner to have a
         * valid storage pointer.
         */
-       if (!task_storage_ptr(task))
+       if (!task || !task_storage_ptr(task))
                return (unsigned long)NULL;
 
        sdata = task_storage_lookup(task, map, true);
@@ -243,6 +243,9 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,
 BPF_CALL_2(bpf_task_storage_delete, struct bpf_map *, map, struct task_struct *,
           task)
 {
+       if (!task)
+               return -EINVAL;
+
        /* This helper must only be called from places where the lifetime of the task
         * is guaranteed. Either by being refcounted or by being protected
         * by an RCU read-side critical section.
index 8d6bdb4..84a36ee 100644 (file)
@@ -4172,7 +4172,7 @@ static int btf_parse_hdr(struct btf_verifier_env *env)
                return -ENOTSUPP;
        }
 
-       if (btf_data_size == hdr->hdr_len) {
+       if (!btf->base_btf && btf_data_size == hdr->hdr_len) {
                btf_verifier_log(env, "No data");
                return -EINVAL;
        }
index 6ec088a..96555a8 100644 (file)
@@ -1391,12 +1391,13 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
                if (ctx.optlen != 0) {
                        *optlen = ctx.optlen;
                        *kernel_optval = ctx.optval;
+                       /* export and don't free sockopt buf */
+                       return 0;
                }
        }
 
 out:
-       if (ret)
-               sockopt_free_buf(&ctx);
+       sockopt_free_buf(&ctx);
        return ret;
 }
 
index bd8a318..41ca280 100644 (file)
@@ -108,7 +108,7 @@ BPF_CALL_2(bpf_map_peek_elem, struct bpf_map *, map, void *, value)
 }
 
 const struct bpf_func_proto bpf_map_peek_elem_proto = {
-       .func           = bpf_map_pop_elem,
+       .func           = bpf_map_peek_elem,
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
        .arg1_type      = ARG_CONST_MAP_PTR,
index c3bb03c..e5999d8 100644 (file)
@@ -2712,7 +2712,6 @@ out_unlock:
 out_put_prog:
        if (tgt_prog_fd && tgt_prog)
                bpf_prog_put(tgt_prog);
-       bpf_prog_put(prog);
        return err;
 }
 
@@ -2825,7 +2824,10 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
                        tp_name = prog->aux->attach_func_name;
                        break;
                }
-               return bpf_tracing_prog_attach(prog, 0, 0);
+               err = bpf_tracing_prog_attach(prog, 0, 0);
+               if (err >= 0)
+                       return err;
+               goto out_put_prog;
        case BPF_PROG_TYPE_RAW_TRACEPOINT:
        case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
                if (strncpy_from_user(buf,
index 17270b8..e7368c5 100644 (file)
@@ -2217,6 +2217,8 @@ static bool is_spillable_regtype(enum bpf_reg_type type)
        case PTR_TO_RDWR_BUF:
        case PTR_TO_RDWR_BUF_OR_NULL:
        case PTR_TO_PERCPU_BTF_ID:
+       case PTR_TO_MEM:
+       case PTR_TO_MEM_OR_NULL:
                return true;
        default:
                return false;
@@ -5311,7 +5313,7 @@ static bool signed_add_overflows(s64 a, s64 b)
        return res < a;
 }
 
-static bool signed_add32_overflows(s64 a, s64 b)
+static bool signed_add32_overflows(s32 a, s32 b)
 {
        /* Do the add in u32, where overflow is well-defined */
        s32 res = (s32)((u32)a + (u32)b);
@@ -5321,7 +5323,7 @@ static bool signed_add32_overflows(s64 a, s64 b)
        return res < a;
 }
 
-static bool signed_sub_overflows(s32 a, s32 b)
+static bool signed_sub_overflows(s64 a, s64 b)
 {
        /* Do the sub in u64, where overflow is well-defined */
        s64 res = (s64)((u64)a - (u64)b);
@@ -5333,7 +5335,7 @@ static bool signed_sub_overflows(s32 a, s32 b)
 
 static bool signed_sub32_overflows(s32 a, s32 b)
 {
-       /* Do the sub in u64, where overflow is well-defined */
+       /* Do the sub in u32, where overflow is well-defined */
        s32 res = (s32)((u32)a - (u32)b);
 
        if (b < 0)
index ffdd0dc..6639a0c 100644 (file)
@@ -1291,11 +1291,16 @@ static size_t info_print_prefix(const struct printk_info  *info, bool syslog,
  * done:
  *
  *   - Add prefix for each line.
+ *   - Drop truncated lines that no longer fit into the buffer.
  *   - Add the trailing newline that has been removed in vprintk_store().
- *   - Drop truncated lines that do not longer fit into the buffer.
+ *   - Add a string terminator.
+ *
+ * Since the produced string is always terminated, the maximum possible
+ * return value is @r->text_buf_size - 1;
  *
  * Return: The length of the updated/prepared text, including the added
- * prefixes and the newline. The dropped line(s) are not counted.
+ * prefixes and the newline. The terminator is not counted. The dropped
+ * line(s) are not counted.
  */
 static size_t record_print_text(struct printk_record *r, bool syslog,
                                bool time)
@@ -1338,26 +1343,31 @@ static size_t record_print_text(struct printk_record *r, bool syslog,
 
                /*
                 * Truncate the text if there is not enough space to add the
-                * prefix and a trailing newline.
+                * prefix and a trailing newline and a terminator.
                 */
-               if (len + prefix_len + text_len + 1 > buf_size) {
+               if (len + prefix_len + text_len + 1 + 1 > buf_size) {
                        /* Drop even the current line if no space. */
-                       if (len + prefix_len + line_len + 1 > buf_size)
+                       if (len + prefix_len + line_len + 1 + 1 > buf_size)
                                break;
 
-                       text_len = buf_size - len - prefix_len - 1;
+                       text_len = buf_size - len - prefix_len - 1 - 1;
                        truncated = true;
                }
 
                memmove(text + prefix_len, text, text_len);
                memcpy(text, prefix, prefix_len);
 
+               /*
+                * Increment the prepared length to include the text and
+                * prefix that were just moved+copied. Also increment for the
+                * newline at the end of this line. If this is the last line,
+                * there is no newline, but it will be added immediately below.
+                */
                len += prefix_len + line_len + 1;
-
                if (text_len == line_len) {
                        /*
-                        * Add the trailing newline removed in
-                        * vprintk_store().
+                        * This is the last line. Add the trailing newline
+                        * removed in vprintk_store().
                         */
                        text[prefix_len + line_len] = '\n';
                        break;
@@ -1382,6 +1392,14 @@ static size_t record_print_text(struct printk_record *r, bool syslog,
                text_len -= line_len + 1;
        }
 
+       /*
+        * If a buffer was provided, it will be terminated. Space for the
+        * string terminator is guaranteed to be available. The terminator is
+        * not counted in the return value.
+        */
+       if (buf_size > 0)
+               text[len] = 0;
+
        return len;
 }
 
@@ -3427,7 +3445,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
        while (prb_read_valid_info(prb, seq, &info, &line_count)) {
                if (r.info->seq >= dumper->next_seq)
                        break;
-               l += get_record_print_text_size(&info, line_count, true, time);
+               l += get_record_print_text_size(&info, line_count, syslog, time);
                seq = r.info->seq + 1;
        }
 
@@ -3437,7 +3455,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
                                                &info, &line_count)) {
                if (r.info->seq >= dumper->next_seq)
                        break;
-               l -= get_record_print_text_size(&info, line_count, true, time);
+               l -= get_record_print_text_size(&info, line_count, syslog, time);
                seq = r.info->seq + 1;
        }
 
index 6704f06..8a7b736 100644 (file)
@@ -1718,7 +1718,7 @@ static bool copy_data(struct prb_data_ring *data_ring,
 
        /* Caller interested in the line count? */
        if (line_count)
-               *line_count = count_lines(data, data_size);
+               *line_count = count_lines(data, len);
 
        /* Caller interested in the data content? */
        if (!buf || !buf_size)
index 5736c55..6b9c431 100644 (file)
@@ -2550,6 +2550,9 @@ bool get_signal(struct ksignal *ksig)
        struct signal_struct *signal = current->signal;
        int signr;
 
+       if (unlikely(current->task_works))
+               task_work_run();
+
        /*
         * For non-generic architectures, check for TIF_NOTIFY_SIGNAL so
         * that the arch handlers don't all have to do it. If we get here
index d24bcfa..1eaaec1 100644 (file)
@@ -1427,7 +1427,7 @@ phys_addr_t __init memblock_phys_alloc_range(phys_addr_t size,
 }
 
 /**
- * memblock_phys_alloc_try_nid - allocate a memory block from specified MUMA node
+ * memblock_phys_alloc_try_nid - allocate a memory block from specified NUMA node
  * @size: size of memory block to be allocated in bytes
  * @align: alignment of the region and block's size
  * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
index c1c30a9..8b796c4 100644 (file)
@@ -272,7 +272,8 @@ int bpf_prog_test_run_raw_tp(struct bpf_prog *prog,
            kattr->test.repeat)
                return -EINVAL;
 
-       if (ctx_size_in < prog->aux->max_ctx_offset)
+       if (ctx_size_in < prog->aux->max_ctx_offset ||
+           ctx_size_in > MAX_BPF_FUNC_ARGS * sizeof(u64))
                return -EINVAL;
 
        if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 && cpu != 0)
index 9815cfe..ca44c32 100644 (file)
@@ -569,6 +569,34 @@ e_range:
        return -ERANGE;
 }
 
+static int decode_con_secret(void **p, void *end, u8 *con_secret,
+                            int *con_secret_len)
+{
+       int len;
+
+       ceph_decode_32_safe(p, end, len, bad);
+       ceph_decode_need(p, end, len, bad);
+
+       dout("%s len %d\n", __func__, len);
+       if (con_secret) {
+               if (len > CEPH_MAX_CON_SECRET_LEN) {
+                       pr_err("connection secret too big %d\n", len);
+                       goto bad_memzero;
+               }
+               memcpy(con_secret, *p, len);
+               *con_secret_len = len;
+       }
+       memzero_explicit(*p, len);
+       *p += len;
+       return 0;
+
+bad_memzero:
+       memzero_explicit(*p, len);
+bad:
+       pr_err("failed to decode connection secret\n");
+       return -EINVAL;
+}
+
 static int handle_auth_session_key(struct ceph_auth_client *ac,
                                   void **p, void *end,
                                   u8 *session_key, int *session_key_len,
@@ -612,17 +640,9 @@ static int handle_auth_session_key(struct ceph_auth_client *ac,
                dout("%s decrypted %d bytes\n", __func__, ret);
                dend = dp + ret;
 
-               ceph_decode_32_safe(&dp, dend, len, e_inval);
-               if (len > CEPH_MAX_CON_SECRET_LEN) {
-                       pr_err("connection secret too big %d\n", len);
-                       return -EINVAL;
-               }
-
-               dout("%s connection secret len %d\n", __func__, len);
-               if (con_secret) {
-                       memcpy(con_secret, dp, len);
-                       *con_secret_len = len;
-               }
+               ret = decode_con_secret(&dp, dend, con_secret, con_secret_len);
+               if (ret)
+                       return ret;
        }
 
        /* service tickets */
@@ -828,7 +848,6 @@ static int decrypt_authorizer_reply(struct ceph_crypto_key *secret,
 {
        void *dp, *dend;
        u8 struct_v;
-       int len;
        int ret;
 
        dp = *p + ceph_x_encrypt_offset();
@@ -843,17 +862,9 @@ static int decrypt_authorizer_reply(struct ceph_crypto_key *secret,
        ceph_decode_64_safe(&dp, dend, *nonce_plus_one, e_inval);
        dout("%s nonce_plus_one %llu\n", __func__, *nonce_plus_one);
        if (struct_v >= 2) {
-               ceph_decode_32_safe(&dp, dend, len, e_inval);
-               if (len > CEPH_MAX_CON_SECRET_LEN) {
-                       pr_err("connection secret too big %d\n", len);
-                       return -EINVAL;
-               }
-
-               dout("%s connection secret len %d\n", __func__, len);
-               if (con_secret) {
-                       memcpy(con_secret, dp, len);
-                       *con_secret_len = len;
-               }
+               ret = decode_con_secret(&dp, dend, con_secret, con_secret_len);
+               if (ret)
+                       return ret;
        }
 
        return 0;
index 4f75df4..92d89b3 100644 (file)
@@ -96,6 +96,7 @@ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
        key->len = ceph_decode_16(p);
        ceph_decode_need(p, end, key->len, bad);
        ret = set_secret(key, *p);
+       memzero_explicit(*p, key->len);
        *p += key->len;
        return ret;
 
@@ -134,7 +135,7 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
 void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
 {
        if (key) {
-               kfree(key->key);
+               kfree_sensitive(key->key);
                key->key = NULL;
                if (key->tfm) {
                        crypto_free_sync_skcipher(key->tfm);
index 04f653b..2cb5ffd 100644 (file)
@@ -1100,7 +1100,7 @@ static int read_partial_message(struct ceph_connection *con)
                if (ret < 0)
                        return ret;
 
-               BUG_ON(!con->in_msg ^ skip);
+               BUG_ON((!con->in_msg) ^ skip);
                if (skip) {
                        /* skip this message */
                        dout("alloc_msg said skip message\n");
index c38d8de..cc40ce4 100644 (file)
@@ -689,11 +689,10 @@ static int verify_epilogue_crcs(struct ceph_connection *con, u32 front_crc,
 }
 
 static int setup_crypto(struct ceph_connection *con,
-                       u8 *session_key, int session_key_len,
-                       u8 *con_secret, int con_secret_len)
+                       const u8 *session_key, int session_key_len,
+                       const u8 *con_secret, int con_secret_len)
 {
        unsigned int noio_flag;
-       void *p;
        int ret;
 
        dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n",
@@ -751,15 +750,14 @@ static int setup_crypto(struct ceph_connection *con,
                return ret;
        }
 
-       p = con_secret;
-       WARN_ON((unsigned long)p & crypto_aead_alignmask(con->v2.gcm_tfm));
-       ret = crypto_aead_setkey(con->v2.gcm_tfm, p, CEPH_GCM_KEY_LEN);
+       WARN_ON((unsigned long)con_secret &
+               crypto_aead_alignmask(con->v2.gcm_tfm));
+       ret = crypto_aead_setkey(con->v2.gcm_tfm, con_secret, CEPH_GCM_KEY_LEN);
        if (ret) {
                pr_err("failed to set gcm key: %d\n", ret);
                return ret;
        }
 
-       p += CEPH_GCM_KEY_LEN;
        WARN_ON(crypto_aead_ivsize(con->v2.gcm_tfm) != CEPH_GCM_IV_LEN);
        ret = crypto_aead_setauthsize(con->v2.gcm_tfm, CEPH_GCM_TAG_LEN);
        if (ret) {
@@ -777,8 +775,11 @@ static int setup_crypto(struct ceph_connection *con,
        aead_request_set_callback(con->v2.gcm_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                  crypto_req_done, &con->v2.gcm_wait);
 
-       memcpy(&con->v2.in_gcm_nonce, p, CEPH_GCM_IV_LEN);
-       memcpy(&con->v2.out_gcm_nonce, p + CEPH_GCM_IV_LEN, CEPH_GCM_IV_LEN);
+       memcpy(&con->v2.in_gcm_nonce, con_secret + CEPH_GCM_KEY_LEN,
+              CEPH_GCM_IV_LEN);
+       memcpy(&con->v2.out_gcm_nonce,
+              con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN,
+              CEPH_GCM_IV_LEN);
        return 0;  /* auth_x, secure mode */
 }
 
@@ -800,7 +801,7 @@ static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs,
        desc->tfm = con->v2.hmac_tfm;
        ret = crypto_shash_init(desc);
        if (ret)
-               return ret;
+               goto out;
 
        for (i = 0; i < kvec_cnt; i++) {
                WARN_ON((unsigned long)kvecs[i].iov_base &
@@ -808,15 +809,14 @@ static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs,
                ret = crypto_shash_update(desc, kvecs[i].iov_base,
                                          kvecs[i].iov_len);
                if (ret)
-                       return ret;
+                       goto out;
        }
 
        ret = crypto_shash_final(desc, hmac);
-       if (ret)
-               return ret;
 
+out:
        shash_desc_zero(desc);
-       return 0;  /* auth_x, both plain and secure modes */
+       return ret;  /* auth_x, both plain and secure modes */
 }
 
 static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce)
@@ -2072,27 +2072,32 @@ static int process_auth_done(struct ceph_connection *con, void *p, void *end)
        if (con->state != CEPH_CON_S_V2_AUTH) {
                dout("%s con %p state changed to %d\n", __func__, con,
                     con->state);
-               return -EAGAIN;
+               ret = -EAGAIN;
+               goto out;
        }
 
        dout("%s con %p handle_auth_done ret %d\n", __func__, con, ret);
        if (ret)
-               return ret;
+               goto out;
 
        ret = setup_crypto(con, session_key, session_key_len, con_secret,
                           con_secret_len);
        if (ret)
-               return ret;
+               goto out;
 
        reset_out_kvecs(con);
        ret = prepare_auth_signature(con);
        if (ret) {
                pr_err("prepare_auth_signature failed: %d\n", ret);
-               return ret;
+               goto out;
        }
 
        con->state = CEPH_CON_S_V2_AUTH_SIGNATURE;
-       return 0;
+
+out:
+       memzero_explicit(session_key_buf, sizeof(session_key_buf));
+       memzero_explicit(con_secret_buf, sizeof(con_secret_buf));
+       return ret;
 
 bad:
        pr_err("failed to decode auth_done\n");
@@ -3436,6 +3441,8 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con)
        }
 
        con->v2.con_mode = CEPH_CON_MODE_UNKNOWN;
+       memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN);
+       memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN);
 
        if (con->v2.hmac_tfm) {
                crypto_free_shash(con->v2.hmac_tfm);
index b9d54ed..195ceb8 100644 (file)
@@ -1433,7 +1433,7 @@ static int mon_handle_auth_bad_method(struct ceph_connection *con,
 /*
  * handle incoming message
  */
-static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+static void mon_dispatch(struct ceph_connection *con, struct ceph_msg *msg)
 {
        struct ceph_mon_client *monc = con->private;
        int type = le16_to_cpu(msg->hdr.type);
@@ -1565,21 +1565,21 @@ static void mon_fault(struct ceph_connection *con)
  * will come from the messenger workqueue, which is drained prior to
  * mon_client destruction.
  */
-static struct ceph_connection *con_get(struct ceph_connection *con)
+static struct ceph_connection *mon_get_con(struct ceph_connection *con)
 {
        return con;
 }
 
-static void con_put(struct ceph_connection *con)
+static void mon_put_con(struct ceph_connection *con)
 {
 }
 
 static const struct ceph_connection_operations mon_con_ops = {
-       .get = con_get,
-       .put = con_put,
-       .dispatch = dispatch,
-       .fault = mon_fault,
+       .get = mon_get_con,
+       .put = mon_put_con,
        .alloc_msg = mon_alloc_msg,
+       .dispatch = mon_dispatch,
+       .fault = mon_fault,
        .get_auth_request = mon_get_auth_request,
        .handle_auth_reply_more = mon_handle_auth_reply_more,
        .handle_auth_done = mon_handle_auth_done,
index 61229c5..ff8624a 100644 (file)
@@ -5412,7 +5412,7 @@ void ceph_osdc_cleanup(void)
 /*
  * handle incoming message
  */
-static void dispatch(struct ceph_connection *con, struct ceph_msg *msg)
+static void osd_dispatch(struct ceph_connection *con, struct ceph_msg *msg)
 {
        struct ceph_osd *osd = con->private;
        struct ceph_osd_client *osdc = osd->o_osdc;
@@ -5534,9 +5534,9 @@ static struct ceph_msg *alloc_msg_with_page_vector(struct ceph_msg_header *hdr)
        return m;
 }
 
-static struct ceph_msg *alloc_msg(struct ceph_connection *con,
-                                 struct ceph_msg_header *hdr,
-                                 int *skip)
+static struct ceph_msg *osd_alloc_msg(struct ceph_connection *con,
+                                     struct ceph_msg_header *hdr,
+                                     int *skip)
 {
        struct ceph_osd *osd = con->private;
        int type = le16_to_cpu(hdr->type);
@@ -5560,7 +5560,7 @@ static struct ceph_msg *alloc_msg(struct ceph_connection *con,
 /*
  * Wrappers to refcount containing ceph_osd struct
  */
-static struct ceph_connection *get_osd_con(struct ceph_connection *con)
+static struct ceph_connection *osd_get_con(struct ceph_connection *con)
 {
        struct ceph_osd *osd = con->private;
        if (get_osd(osd))
@@ -5568,7 +5568,7 @@ static struct ceph_connection *get_osd_con(struct ceph_connection *con)
        return NULL;
 }
 
-static void put_osd_con(struct ceph_connection *con)
+static void osd_put_con(struct ceph_connection *con)
 {
        struct ceph_osd *osd = con->private;
        put_osd(osd);
@@ -5582,8 +5582,8 @@ static void put_osd_con(struct ceph_connection *con)
  * Note: returned pointer is the address of a structure that's
  * managed separately.  Caller must *not* attempt to free it.
  */
-static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
-                                       int *proto, int force_new)
+static struct ceph_auth_handshake *
+osd_get_authorizer(struct ceph_connection *con, int *proto, int force_new)
 {
        struct ceph_osd *o = con->private;
        struct ceph_osd_client *osdc = o->o_osdc;
@@ -5599,7 +5599,7 @@ static struct ceph_auth_handshake *get_authorizer(struct ceph_connection *con,
        return auth;
 }
 
-static int add_authorizer_challenge(struct ceph_connection *con,
+static int osd_add_authorizer_challenge(struct ceph_connection *con,
                                    void *challenge_buf, int challenge_buf_len)
 {
        struct ceph_osd *o = con->private;
@@ -5610,7 +5610,7 @@ static int add_authorizer_challenge(struct ceph_connection *con,
                                            challenge_buf, challenge_buf_len);
 }
 
-static int verify_authorizer_reply(struct ceph_connection *con)
+static int osd_verify_authorizer_reply(struct ceph_connection *con)
 {
        struct ceph_osd *o = con->private;
        struct ceph_osd_client *osdc = o->o_osdc;
@@ -5622,7 +5622,7 @@ static int verify_authorizer_reply(struct ceph_connection *con)
                NULL, NULL, NULL, NULL);
 }
 
-static int invalidate_authorizer(struct ceph_connection *con)
+static int osd_invalidate_authorizer(struct ceph_connection *con)
 {
        struct ceph_osd *o = con->private;
        struct ceph_osd_client *osdc = o->o_osdc;
@@ -5731,18 +5731,18 @@ static int osd_check_message_signature(struct ceph_msg *msg)
 }
 
 static const struct ceph_connection_operations osd_con_ops = {
-       .get = get_osd_con,
-       .put = put_osd_con,
-       .dispatch = dispatch,
-       .get_authorizer = get_authorizer,
-       .add_authorizer_challenge = add_authorizer_challenge,
-       .verify_authorizer_reply = verify_authorizer_reply,
-       .invalidate_authorizer = invalidate_authorizer,
-       .alloc_msg = alloc_msg,
+       .get = osd_get_con,
+       .put = osd_put_con,
+       .alloc_msg = osd_alloc_msg,
+       .dispatch = osd_dispatch,
+       .fault = osd_fault,
        .reencode_message = osd_reencode_message,
+       .get_authorizer = osd_get_authorizer,
+       .add_authorizer_challenge = osd_add_authorizer_challenge,
+       .verify_authorizer_reply = osd_verify_authorizer_reply,
+       .invalidate_authorizer = osd_invalidate_authorizer,
        .sign_message = osd_sign_message,
        .check_message_signature = osd_check_message_signature,
-       .fault = osd_fault,
        .get_auth_request = osd_get_auth_request,
        .handle_auth_reply_more = osd_handle_auth_reply_more,
        .handle_auth_done = osd_handle_auth_done,
index c360bb5..a979b86 100644 (file)
@@ -9672,6 +9672,11 @@ static netdev_features_t netdev_fix_features(struct net_device *dev,
                }
        }
 
+       if ((features & NETIF_F_HW_TLS_RX) && !(features & NETIF_F_RXCSUM)) {
+               netdev_dbg(dev, "Dropping TLS RX HW offload feature since no RXCSUM feature.\n");
+               features &= ~NETIF_F_HW_TLS_RX;
+       }
+
        return features;
 }
 
index ee828e4..738d434 100644 (file)
@@ -4146,7 +4146,7 @@ out:
 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
                                              struct genl_info *info)
 {
-       struct devlink_port *devlink_port = info->user_ptr[0];
+       struct devlink_port *devlink_port = info->user_ptr[1];
        struct devlink_param_item *param_item;
        struct sk_buff *msg;
        int err;
@@ -4175,7 +4175,7 @@ static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
                                              struct genl_info *info)
 {
-       struct devlink_port *devlink_port = info->user_ptr[0];
+       struct devlink_port *devlink_port = info->user_ptr[1];
 
        return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
                                               devlink_port->index,
index 80dbf2f..8e582e2 100644 (file)
@@ -80,11 +80,11 @@ static void est_timer(struct timer_list *t)
        u64 rate, brate;
 
        est_fetch_counters(est, &b);
-       brate = (b.bytes - est->last_bytes) << (10 - est->ewma_log - est->intvl_log);
-       brate -= (est->avbps >> est->ewma_log);
+       brate = (b.bytes - est->last_bytes) << (10 - est->intvl_log);
+       brate = (brate >> est->ewma_log) - (est->avbps >> est->ewma_log);
 
-       rate = (b.packets - est->last_packets) << (10 - est->ewma_log - est->intvl_log);
-       rate -= (est->avpps >> est->ewma_log);
+       rate = (b.packets - est->last_packets) << (10 - est->intvl_log);
+       rate = (rate >> est->ewma_log) - (est->avpps >> est->ewma_log);
 
        write_seqcount_begin(&est->seq);
        est->avbps += brate;
@@ -143,6 +143,9 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
        if (parm->interval < -2 || parm->interval > 3)
                return -EINVAL;
 
+       if (parm->ewma_log == 0 || parm->ewma_log >= 31)
+               return -EINVAL;
+
        est = kzalloc(sizeof(*est), GFP_KERNEL);
        if (!est)
                return -ENOBUFS;
index c1a6f26..785daff 100644 (file)
@@ -437,7 +437,11 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,
 
        len += NET_SKB_PAD;
 
-       if ((len > SKB_WITH_OVERHEAD(PAGE_SIZE)) ||
+       /* If requested length is either too small or too big,
+        * we use kmalloc() for skb->head allocation.
+        */
+       if (len <= SKB_WITH_OVERHEAD(1024) ||
+           len > SKB_WITH_OVERHEAD(PAGE_SIZE) ||
            (gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) {
                skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE);
                if (!skb)
index fd8b880..6bd7ca0 100644 (file)
@@ -851,6 +851,7 @@ struct sock *inet_csk_clone_lock(const struct sock *sk,
                newicsk->icsk_retransmits = 0;
                newicsk->icsk_backoff     = 0;
                newicsk->icsk_probes_out  = 0;
+               newicsk->icsk_probes_tstamp = 0;
 
                /* Deinitialize accept_queue to trap illegal accesses. */
                memset(&newicsk->icsk_accept_queue, 0, sizeof(newicsk->icsk_accept_queue));
index cc23f1c..8cd3224 100644 (file)
@@ -76,7 +76,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
        flow.daddr = iph->saddr;
        flow.saddr = rpfilter_get_saddr(iph->daddr);
        flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
-       flow.flowi4_tos = RT_TOS(iph->tos);
+       flow.flowi4_tos = iph->tos & IPTOS_RT_MASK;
        flow.flowi4_scope = RT_SCOPE_UNIVERSE;
        flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par));
 
index ed42d21..32545ec 100644 (file)
@@ -2937,6 +2937,7 @@ int tcp_disconnect(struct sock *sk, int flags)
 
        icsk->icsk_backoff = 0;
        icsk->icsk_probes_out = 0;
+       icsk->icsk_probes_tstamp = 0;
        icsk->icsk_rto = TCP_TIMEOUT_INIT;
        icsk->icsk_rto_min = TCP_RTO_MIN;
        icsk->icsk_delack_max = TCP_DELACK_MAX;
index c7e16b0..a7dfca0 100644 (file)
@@ -3384,6 +3384,7 @@ static void tcp_ack_probe(struct sock *sk)
                return;
        if (!after(TCP_SKB_CB(head)->end_seq, tcp_wnd_end(tp))) {
                icsk->icsk_backoff = 0;
+               icsk->icsk_probes_tstamp = 0;
                inet_csk_clear_xmit_timer(sk, ICSK_TIME_PROBE0);
                /* Socket must be waked up by subsequent tcp_data_snd_check().
                 * This function is not for random using!
@@ -4396,10 +4397,9 @@ static void tcp_rcv_spurious_retrans(struct sock *sk, const struct sk_buff *skb)
         * The receiver remembers and reflects via DSACKs. Leverage the
         * DSACK state and change the txhash to re-route speculatively.
         */
-       if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq) {
-               sk_rethink_txhash(sk);
+       if (TCP_SKB_CB(skb)->seq == tcp_sk(sk)->duplicate_sack[0].start_seq &&
+           sk_rethink_txhash(sk))
                NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDUPLICATEDATAREHASH);
-       }
 }
 
 static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
index 58207c7..777306b 100644 (file)
@@ -1595,6 +1595,8 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
                tcp_move_syn(newtp, req);
                ireq->ireq_opt = NULL;
        } else {
+               newinet->inet_opt = NULL;
+
                if (!req_unhash && found_dup_sk) {
                        /* This code path should only be executed in the
                         * syncookie case only
@@ -1602,8 +1604,6 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
                        bh_unlock_sock(newsk);
                        sock_put(newsk);
                        newsk = NULL;
-               } else {
-                       newinet->inet_opt = NULL;
                }
        }
        return newsk;
@@ -1760,6 +1760,7 @@ int tcp_v4_early_demux(struct sk_buff *skb)
 bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
        u32 limit = READ_ONCE(sk->sk_rcvbuf) + READ_ONCE(sk->sk_sndbuf);
+       u32 tail_gso_size, tail_gso_segs;
        struct skb_shared_info *shinfo;
        const struct tcphdr *th;
        struct tcphdr *thtail;
@@ -1767,6 +1768,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
        unsigned int hdrlen;
        bool fragstolen;
        u32 gso_segs;
+       u32 gso_size;
        int delta;
 
        /* In case all data was pulled from skb frags (in __pskb_pull_tail()),
@@ -1792,13 +1794,6 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
         */
        th = (const struct tcphdr *)skb->data;
        hdrlen = th->doff * 4;
-       shinfo = skb_shinfo(skb);
-
-       if (!shinfo->gso_size)
-               shinfo->gso_size = skb->len - hdrlen;
-
-       if (!shinfo->gso_segs)
-               shinfo->gso_segs = 1;
 
        tail = sk->sk_backlog.tail;
        if (!tail)
@@ -1821,6 +1816,15 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
                goto no_coalesce;
 
        __skb_pull(skb, hdrlen);
+
+       shinfo = skb_shinfo(skb);
+       gso_size = shinfo->gso_size ?: skb->len;
+       gso_segs = shinfo->gso_segs ?: 1;
+
+       shinfo = skb_shinfo(tail);
+       tail_gso_size = shinfo->gso_size ?: (tail->len - hdrlen);
+       tail_gso_segs = shinfo->gso_segs ?: 1;
+
        if (skb_try_coalesce(tail, skb, &fragstolen, &delta)) {
                TCP_SKB_CB(tail)->end_seq = TCP_SKB_CB(skb)->end_seq;
 
@@ -1847,11 +1851,8 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb)
                }
 
                /* Not as strict as GRO. We only need to carry mss max value */
-               skb_shinfo(tail)->gso_size = max(shinfo->gso_size,
-                                                skb_shinfo(tail)->gso_size);
-
-               gso_segs = skb_shinfo(tail)->gso_segs + shinfo->gso_segs;
-               skb_shinfo(tail)->gso_segs = min_t(u32, gso_segs, 0xFFFF);
+               shinfo->gso_size = max(gso_size, tail_gso_size);
+               shinfo->gso_segs = min_t(u32, gso_segs + tail_gso_segs, 0xFFFF);
 
                sk->sk_backlog.len += delta;
                __NET_INC_STATS(sock_net(sk),
index f322e79..ab45869 100644 (file)
@@ -4084,6 +4084,7 @@ void tcp_send_probe0(struct sock *sk)
                /* Cancel probe timer, if it is not required. */
                icsk->icsk_probes_out = 0;
                icsk->icsk_backoff = 0;
+               icsk->icsk_probes_tstamp = 0;
                return;
        }
 
index 6c62b9e..faa9294 100644 (file)
@@ -219,14 +219,8 @@ static int tcp_write_timeout(struct sock *sk)
        int retry_until;
 
        if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
-               if (icsk->icsk_retransmits) {
-                       dst_negative_advice(sk);
-               } else {
-                       sk_rethink_txhash(sk);
-                       tp->timeout_rehash++;
-                       __NET_INC_STATS(sock_net(sk),
-                                       LINUX_MIB_TCPTIMEOUTREHASH);
-               }
+               if (icsk->icsk_retransmits)
+                       __dst_negative_advice(sk);
                retry_until = icsk->icsk_syn_retries ? : net->ipv4.sysctl_tcp_syn_retries;
                expired = icsk->icsk_retransmits >= retry_until;
        } else {
@@ -234,12 +228,7 @@ static int tcp_write_timeout(struct sock *sk)
                        /* Black hole detection */
                        tcp_mtu_probing(icsk, sk);
 
-                       dst_negative_advice(sk);
-               } else {
-                       sk_rethink_txhash(sk);
-                       tp->timeout_rehash++;
-                       __NET_INC_STATS(sock_net(sk),
-                                       LINUX_MIB_TCPTIMEOUTREHASH);
+                       __dst_negative_advice(sk);
                }
 
                retry_until = net->ipv4.sysctl_tcp_retries2;
@@ -270,6 +259,11 @@ static int tcp_write_timeout(struct sock *sk)
                return 1;
        }
 
+       if (sk_rethink_txhash(sk)) {
+               tp->timeout_rehash++;
+               __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPTIMEOUTREHASH);
+       }
+
        return 0;
 }
 
@@ -349,6 +343,7 @@ static void tcp_probe_timer(struct sock *sk)
 
        if (tp->packets_out || !skb) {
                icsk->icsk_probes_out = 0;
+               icsk->icsk_probes_tstamp = 0;
                return;
        }
 
@@ -360,13 +355,12 @@ static void tcp_probe_timer(struct sock *sk)
         * corresponding system limit. We also implement similar policy when
         * we use RTO to probe window in tcp_retransmit_timer().
         */
-       if (icsk->icsk_user_timeout) {
-               u32 elapsed = tcp_model_timeout(sk, icsk->icsk_probes_out,
-                                               tcp_probe0_base(sk));
-
-               if (elapsed >= icsk->icsk_user_timeout)
-                       goto abort;
-       }
+       if (!icsk->icsk_probes_tstamp)
+               icsk->icsk_probes_tstamp = tcp_jiffies32;
+       else if (icsk->icsk_user_timeout &&
+                (s32)(tcp_jiffies32 - icsk->icsk_probes_tstamp) >=
+                msecs_to_jiffies(icsk->icsk_user_timeout))
+               goto abort;
 
        max_probes = sock_net(sk)->ipv4.sysctl_tcp_retries2;
        if (sock_flag(sk, SOCK_DEAD)) {
index 7103b0a..69ea765 100644 (file)
@@ -2555,7 +2555,8 @@ int udp_v4_early_demux(struct sk_buff *skb)
                 */
                if (!inet_sk(sk)->inet_daddr && in_dev)
                        return ip_mc_validate_source(skb, iph->daddr,
-                                                    iph->saddr, iph->tos,
+                                                    iph->saddr,
+                                                    iph->tos & IPTOS_RT_MASK,
                                                     skb->dev, in_dev, &itag);
        }
        return 0;
index eff2cac..9edc5bb 100644 (file)
@@ -2467,8 +2467,9 @@ static void addrconf_add_mroute(struct net_device *dev)
                .fc_ifindex = dev->ifindex,
                .fc_dst_len = 8,
                .fc_flags = RTF_UP,
-               .fc_type = RTN_UNICAST,
+               .fc_type = RTN_MULTICAST,
                .fc_nlinfo.nl_net = dev_net(dev),
+               .fc_protocol = RTPROT_KERNEL,
        };
 
        ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
index 48f144f..9e723d9 100644 (file)
@@ -120,18 +120,17 @@ static ssize_t aqm_write(struct file *file,
 {
        struct ieee80211_local *local = file->private_data;
        char buf[100];
-       size_t len;
 
-       if (count > sizeof(buf))
+       if (count >= sizeof(buf))
                return -EINVAL;
 
        if (copy_from_user(buf, user_buf, count))
                return -EFAULT;
 
-       buf[sizeof(buf) - 1] = '\0';
-       len = strlen(buf);
-       if (len > 0 && buf[len-1] == '\n')
-               buf[len-1] = 0;
+       if (count && buf[count - 1] == '\n')
+               buf[count - 1] = '\0';
+       else
+               buf[count] = '\0';
 
        if (sscanf(buf, "fq_limit %u", &local->fq.limit) == 1)
                return count;
@@ -177,18 +176,17 @@ static ssize_t airtime_flags_write(struct file *file,
 {
        struct ieee80211_local *local = file->private_data;
        char buf[16];
-       size_t len;
 
-       if (count > sizeof(buf))
+       if (count >= sizeof(buf))
                return -EINVAL;
 
        if (copy_from_user(buf, user_buf, count))
                return -EFAULT;
 
-       buf[sizeof(buf) - 1] = 0;
-       len = strlen(buf);
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = 0;
+       if (count && buf[count - 1] == '\n')
+               buf[count - 1] = '\0';
+       else
+               buf[count] = '\0';
 
        if (kstrtou16(buf, 0, &local->airtime_flags))
                return -EINVAL;
@@ -237,20 +235,19 @@ static ssize_t aql_txq_limit_write(struct file *file,
 {
        struct ieee80211_local *local = file->private_data;
        char buf[100];
-       size_t len;
        u32 ac, q_limit_low, q_limit_high, q_limit_low_old, q_limit_high_old;
        struct sta_info *sta;
 
-       if (count > sizeof(buf))
+       if (count >= sizeof(buf))
                return -EINVAL;
 
        if (copy_from_user(buf, user_buf, count))
                return -EFAULT;
 
-       buf[sizeof(buf) - 1] = 0;
-       len = strlen(buf);
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = 0;
+       if (count && buf[count - 1] == '\n')
+               buf[count - 1] = '\0';
+       else
+               buf[count] = '\0';
 
        if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
                return -EINVAL;
@@ -306,18 +303,17 @@ static ssize_t force_tx_status_write(struct file *file,
 {
        struct ieee80211_local *local = file->private_data;
        char buf[3];
-       size_t len;
 
-       if (count > sizeof(buf))
+       if (count >= sizeof(buf))
                return -EINVAL;
 
        if (copy_from_user(buf, user_buf, count))
                return -EFAULT;
 
-       buf[sizeof(buf) - 1] = '\0';
-       len = strlen(buf);
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = 0;
+       if (count && buf[count - 1] == '\n')
+               buf[count - 1] = '\0';
+       else
+               buf[count] = '\0';
 
        if (buf[0] == '0' && buf[1] == '\0')
                local->force_tx_status = 0;
index 13b9bcc..972895e 100644 (file)
@@ -4176,6 +4176,8 @@ void ieee80211_check_fast_rx(struct sta_info *sta)
 
        rcu_read_lock();
        key = rcu_dereference(sta->ptk[sta->ptk_idx]);
+       if (!key)
+               key = rcu_dereference(sdata->default_unicast_key);
        if (key) {
                switch (key->conf.cipher) {
                case WLAN_CIPHER_SUITE_TKIP:
index 6422da6..ebb3228 100644 (file)
@@ -649,7 +649,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
                if (!skip_hw && tx->key &&
                    tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
                        info->control.hw_key = &tx->key->conf;
-       } else if (!ieee80211_is_mgmt(hdr->frame_control) && tx->sta &&
+       } else if (ieee80211_is_data_present(hdr->frame_control) && tx->sta &&
                   test_sta_flag(tx->sta, WLAN_STA_USES_ENCRYPTION)) {
                return TX_DROP;
        }
@@ -3809,7 +3809,7 @@ void __ieee80211_schedule_txq(struct ieee80211_hw *hw,
                 * get immediately moved to the back of the list on the next
                 * call to ieee80211_next_txq().
                 */
-               if (txqi->txq.sta &&
+               if (txqi->txq.sta && local->airtime_flags &&
                    wiphy_ext_feature_isset(local->hw.wiphy,
                                            NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
                        list_add(&txqi->schedule_order,
@@ -4251,7 +4251,6 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
        struct ethhdr *ehdr = (struct ethhdr *)skb->data;
        struct ieee80211_key *key;
        struct sta_info *sta;
-       bool offload = true;
 
        if (unlikely(skb->len < ETH_HLEN)) {
                kfree_skb(skb);
@@ -4267,18 +4266,22 @@ netdev_tx_t ieee80211_subif_start_xmit_8023(struct sk_buff *skb,
 
        if (unlikely(IS_ERR_OR_NULL(sta) || !sta->uploaded ||
            !test_sta_flag(sta, WLAN_STA_AUTHORIZED) ||
-               sdata->control_port_protocol == ehdr->h_proto))
-               offload = false;
-       else if ((key = rcu_dereference(sta->ptk[sta->ptk_idx])) &&
-                (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
-                 key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
-               offload = false;
-
-       if (offload)
-               ieee80211_8023_xmit(sdata, dev, sta, key, skb);
-       else
-               ieee80211_subif_start_xmit(skb, dev);
+           sdata->control_port_protocol == ehdr->h_proto))
+               goto skip_offload;
+
+       key = rcu_dereference(sta->ptk[sta->ptk_idx]);
+       if (!key)
+               key = rcu_dereference(sdata->default_unicast_key);
+
+       if (key && (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) ||
+                   key->conf.cipher == WLAN_CIPHER_SUITE_TKIP))
+               goto skip_offload;
+
+       ieee80211_8023_xmit(sdata, dev, sta, key, skb);
+       goto out;
 
+skip_offload:
+       ieee80211_subif_start_xmit(skb, dev);
 out:
        rcu_read_unlock();
 
index e64727e..02a1f13 100644 (file)
@@ -508,7 +508,7 @@ static int nci_open_device(struct nci_dev *ndev)
                };
                unsigned long opt = 0;
 
-               if (!(ndev->nci_ver & NCI_VER_2_MASK))
+               if (ndev->nci_ver & NCI_VER_2_MASK)
                        opt = (unsigned long)&nci_init_v2_cmd;
 
                rc = __nci_request(ndev, nci_init_req, opt,
index 1319986..84f9325 100644 (file)
@@ -1272,6 +1272,10 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
 
                nla_opt_msk = nla_data(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
                msk_depth = nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS_MASK]);
+               if (!nla_ok(nla_opt_msk, msk_depth)) {
+                       NL_SET_ERR_MSG(extack, "Invalid nested attribute for masks");
+                       return -EINVAL;
+               }
        }
 
        nla_for_each_attr(nla_opt_key, nla_enc_key,
@@ -1307,9 +1311,6 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
                                NL_SET_ERR_MSG(extack, "Key and mask miss aligned");
                                return -EINVAL;
                        }
-
-                       if (msk_depth)
-                               nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
                        break;
                case TCA_FLOWER_KEY_ENC_OPTS_VXLAN:
                        if (key->enc_opts.dst_opt_type) {
@@ -1340,9 +1341,6 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
                                NL_SET_ERR_MSG(extack, "Key and mask miss aligned");
                                return -EINVAL;
                        }
-
-                       if (msk_depth)
-                               nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
                        break;
                case TCA_FLOWER_KEY_ENC_OPTS_ERSPAN:
                        if (key->enc_opts.dst_opt_type) {
@@ -1373,14 +1371,20 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
                                NL_SET_ERR_MSG(extack, "Key and mask miss aligned");
                                return -EINVAL;
                        }
-
-                       if (msk_depth)
-                               nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
                        break;
                default:
                        NL_SET_ERR_MSG(extack, "Unknown tunnel option type");
                        return -EINVAL;
                }
+
+               if (!msk_depth)
+                       continue;
+
+               if (!nla_ok(nla_opt_msk, msk_depth)) {
+                       NL_SET_ERR_MSG(extack, "A mask attribute is invalid");
+                       return -EINVAL;
+               }
+               nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
        }
 
        return 0;
index 78bec34..c4007b9 100644 (file)
@@ -366,9 +366,13 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
        if (tb[TCA_TCINDEX_MASK])
                cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
 
-       if (tb[TCA_TCINDEX_SHIFT])
+       if (tb[TCA_TCINDEX_SHIFT]) {
                cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
-
+               if (cp->shift > 16) {
+                       err = -EINVAL;
+                       goto errout;
+               }
+       }
        if (!cp->hash) {
                /* Hash not specified, use perfect hash if the upper limit
                 * of the hashing index is below the threshold.
index 51cb553..6fe4e5c 100644 (file)
@@ -412,7 +412,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 {
        struct qdisc_rate_table *rtab;
 
-       if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
+       if (tab == NULL || r->rate == 0 ||
+           r->cell_log == 0 || r->cell_log >= 32 ||
            nla_len(tab) != TC_RTAB_SIZE) {
                NL_SET_ERR_MSG(extack, "Invalid rate table parameters for searching");
                return NULL;
index 5fb9164..dcc50ae 100644 (file)
@@ -857,6 +857,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
        err = -EAGAIN;
        if (len <= 0)
                goto out_release;
+       trace_svc_xdr_recvfrom(&rqstp->rq_arg);
 
        clear_bit(XPT_OLD, &xprt->xpt_flags);
 
@@ -866,7 +867,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
 
        if (serv->sv_stats)
                serv->sv_stats->netcnt++;
-       trace_svc_xdr_recvfrom(rqstp, &rqstp->rq_arg);
        return len;
 out_release:
        rqstp->rq_res.len = 0;
@@ -904,7 +904,7 @@ int svc_send(struct svc_rqst *rqstp)
        xb->len = xb->head[0].iov_len +
                xb->page_len +
                xb->tail[0].iov_len;
-       trace_svc_xdr_sendto(rqstp, xb);
+       trace_svc_xdr_sendto(rqstp->rq_xid, xb);
        trace_svc_stats_latency(rqstp);
 
        len = xprt->xpt_ops->xpo_sendto(rqstp);
index bb72447..8114bba 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
  * Copyright      2017  Intel Deutschland GmbH
- * Copyright (C) 2018 - 2019 Intel Corporation
+ * Copyright (C) 2018 - 2021 Intel Corporation
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -139,6 +139,11 @@ static const struct ieee80211_regdomain *get_cfg80211_regdom(void)
        return rcu_dereference_rtnl(cfg80211_regdomain);
 }
 
+/*
+ * Returns the regulatory domain associated with the wiphy.
+ *
+ * Requires either RTNL or RCU protection
+ */
 const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
 {
        return rcu_dereference_rtnl(wiphy->regd);
@@ -2571,9 +2576,13 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
        if (IS_ERR(new_regd))
                return;
 
+       rtnl_lock();
+
        tmp = get_wiphy_regdom(wiphy);
        rcu_assign_pointer(wiphy->regd, new_regd);
        rcu_free_regdom(tmp);
+
+       rtnl_unlock();
 }
 EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
 
index 8037b04..4a83117 100644 (file)
@@ -108,9 +108,9 @@ EXPORT_SYMBOL(xsk_get_pool_from_qid);
 
 void xsk_clear_pool_at_qid(struct net_device *dev, u16 queue_id)
 {
-       if (queue_id < dev->real_num_rx_queues)
+       if (queue_id < dev->num_rx_queues)
                dev->_rx[queue_id].pool = NULL;
-       if (queue_id < dev->real_num_tx_queues)
+       if (queue_id < dev->num_tx_queues)
                dev->_tx[queue_id].pool = NULL;
 }
 
index 11554d0..1b8409e 100644 (file)
@@ -611,7 +611,8 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
 
        if (info->is_midi) {
                struct midi_info minf;
-               snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf);
+               if (snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf))
+                       return -ENXIO;
                inf->synth_type = SYNTH_TYPE_MIDI;
                inf->synth_subtype = 0;
                inf->nr_voices = 16;
index 687216e..eec1775 100644 (file)
@@ -2934,7 +2934,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
        snd_hdac_leave_pm(&codec->core);
 }
 
-static int hda_codec_suspend(struct device *dev)
+static int hda_codec_runtime_suspend(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
        unsigned int state;
@@ -2953,7 +2953,7 @@ static int hda_codec_suspend(struct device *dev)
        return 0;
 }
 
-static int hda_codec_resume(struct device *dev)
+static int hda_codec_runtime_resume(struct device *dev)
 {
        struct hda_codec *codec = dev_to_hda_codec(dev);
 
@@ -2968,16 +2968,6 @@ static int hda_codec_resume(struct device *dev)
        return 0;
 }
 
-static int hda_codec_runtime_suspend(struct device *dev)
-{
-       return hda_codec_suspend(dev);
-}
-
-static int hda_codec_runtime_resume(struct device *dev)
-{
-       return hda_codec_resume(dev);
-}
-
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PM_SLEEP
@@ -2998,31 +2988,31 @@ static void hda_codec_pm_complete(struct device *dev)
 static int hda_codec_pm_suspend(struct device *dev)
 {
        dev->power.power_state = PMSG_SUSPEND;
-       return hda_codec_suspend(dev);
+       return pm_runtime_force_suspend(dev);
 }
 
 static int hda_codec_pm_resume(struct device *dev)
 {
        dev->power.power_state = PMSG_RESUME;
-       return hda_codec_resume(dev);
+       return pm_runtime_force_resume(dev);
 }
 
 static int hda_codec_pm_freeze(struct device *dev)
 {
        dev->power.power_state = PMSG_FREEZE;
-       return hda_codec_suspend(dev);
+       return pm_runtime_force_suspend(dev);
 }
 
 static int hda_codec_pm_thaw(struct device *dev)
 {
        dev->power.power_state = PMSG_THAW;
-       return hda_codec_resume(dev);
+       return pm_runtime_force_resume(dev);
 }
 
 static int hda_codec_pm_restore(struct device *dev)
 {
        dev->power.power_state = PMSG_RESTORE;
-       return hda_codec_resume(dev);
+       return pm_runtime_force_resume(dev);
 }
 #endif /* CONFIG_PM_SLEEP */
 
index e4dd2ff..5a50d3a 100644 (file)
@@ -2484,6 +2484,9 @@ static const struct pci_device_id azx_ids[] = {
        /* CometLake-S */
        { PCI_DEVICE(0x8086, 0xa3f0),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+       /* CometLake-R */
+       { PCI_DEVICE(0x8086, 0xf0c8),
+         .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
        /* Icelake */
        { PCI_DEVICE(0x8086, 0x34c8),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
@@ -2507,6 +2510,9 @@ static const struct pci_device_id azx_ids[] = {
        /* Alderlake-S */
        { PCI_DEVICE(0x8086, 0x7ad0),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+       /* Alderlake-P */
+       { PCI_DEVICE(0x8086, 0x51c8),
+         .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
        /* Elkhart Lake */
        { PCI_DEVICE(0x8086, 0x4b55),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
index 74d246a..97adff0 100644 (file)
@@ -4346,6 +4346,7 @@ HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",       patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI",  patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI",        patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI",  patch_i915_tgl_hdmi),
+HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi),
 HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI",        patch_i915_icl_hdmi),
index dd82ff2..ed5b6b8 100644 (file)
@@ -6371,6 +6371,7 @@ enum {
        ALC256_FIXUP_HP_HEADSET_MIC,
        ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
        ALC282_FIXUP_ACER_DISABLE_LINEOUT,
+       ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -7808,6 +7809,12 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC269_FIXUP_HEADSET_MODE
        },
+       [ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc269_fixup_limit_int_mic_boost,
+               .chained = true,
+               .chain_id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7826,6 +7833,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
        SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
+       SND_PCI_QUIRK(0x1025, 0x1094, "Acer Aspire E5-575T", ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK),
index 0ab40a8..834367d 100644 (file)
@@ -113,6 +113,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
                spec->codec_type = VT1708S;
        spec->gen.indep_hp = 1;
        spec->gen.keep_eapd_on = 1;
+       spec->gen.dac_min_mute = 1;
        spec->gen.pcm_playback_hook = via_playback_pcm_hook;
        spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
        codec->power_save_node = 1;
index d5fcc4d..0f3ac22 100644 (file)
@@ -717,7 +717,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component,
                               void *data)
 {
        struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
-       int ret = -EOPNOTSUPP;
+       int ret = -ENOTSUPP;
 
        if (hcp->hcd.ops->hook_plugged_cb) {
                hcp->jack = jack;
index ede4a9a..dbbb761 100644 (file)
@@ -90,7 +90,7 @@ static int imx_hdmi_init(struct snd_soc_pcm_runtime *rtd)
        }
 
        ret = snd_soc_component_set_jack(component, &data->hdmi_jack, NULL);
-       if (ret && ret != -EOPNOTSUPP) {
+       if (ret && ret != -ENOTSUPP) {
                dev_err(card->dev, "Can't set HDMI Jack %d\n", ret);
                return ret;
        }
index 6875fa5..6744318 100644 (file)
@@ -63,16 +63,18 @@ static int hda_codec_load_module(struct hda_codec *codec)
 }
 
 /* enable controller wake up event for all codecs with jack connectors */
-void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
+void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable)
 {
        struct hda_bus *hbus = sof_to_hbus(sdev);
        struct hdac_bus *bus = sof_to_bus(sdev);
        struct hda_codec *codec;
        unsigned int mask = 0;
 
-       list_for_each_codec(codec, hbus)
-               if (codec->jacktbl.used)
-                       mask |= BIT(codec->core.addr);
+       if (enable) {
+               list_for_each_codec(codec, hbus)
+                       if (codec->jacktbl.used)
+                               mask |= BIT(codec->core.addr);
+       }
 
        snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
 }
@@ -81,23 +83,18 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
 void hda_codec_jack_check(struct snd_sof_dev *sdev)
 {
        struct hda_bus *hbus = sof_to_hbus(sdev);
-       struct hdac_bus *bus = sof_to_bus(sdev);
        struct hda_codec *codec;
 
-       /* disable controller Wake Up event*/
-       snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
-
        list_for_each_codec(codec, hbus)
                /*
                 * Wake up all jack-detecting codecs regardless whether an event
                 * has been recorded in STATESTS
                 */
                if (codec->jacktbl.used)
-                       schedule_delayed_work(&codec->jackpoll_work,
-                                             codec->jackpoll_interval);
+                       pm_request_resume(&codec->core.dev);
 }
 #else
-void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
+void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) {}
 void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
 #endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
 EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
@@ -156,7 +153,8 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
                if (!hdev->bus->audio_component) {
                        dev_dbg(sdev->dev,
                                "iDisp hw present but no driver\n");
-                       goto error;
+                       ret = -ENOENT;
+                       goto out;
                }
                hda_priv->need_display_power = true;
        }
@@ -173,24 +171,23 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
                 * other return codes without modification
                 */
                if (ret == 0)
-                       goto error;
+                       ret = -ENOENT;
        }
 
-       return ret;
-
-error:
-       snd_hdac_ext_bus_device_exit(hdev);
-       return -ENOENT;
-
+out:
+       if (ret < 0) {
+               snd_hdac_device_unregister(hdev);
+               put_device(&hdev->dev);
+       }
 #else
        hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
        if (!hdev)
                return -ENOMEM;
 
        ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, HDA_DEV_ASOC);
+#endif
 
        return ret;
-#endif
 }
 
 /* Codec initialization */
index 2b00115..1c5e05b 100644 (file)
@@ -617,7 +617,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
        if (runtime_suspend)
-               hda_codec_jack_wake_enable(sdev);
+               hda_codec_jack_wake_enable(sdev, true);
 
        /* power down all hda link */
        snd_hdac_ext_bus_link_power_down_all(bus);
@@ -683,8 +683,11 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
        /* check jack status */
-       if (runtime_resume)
-               hda_codec_jack_check(sdev);
+       if (runtime_resume) {
+               hda_codec_jack_wake_enable(sdev, false);
+               if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
+                       hda_codec_jack_check(sdev);
+       }
 
        /* turn off the links that were off before suspend */
        list_for_each_entry(hlink, &bus->hlink_list, list) {
index 9ec8ae0..a3b6f3e 100644 (file)
@@ -650,7 +650,7 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev);
  */
 void hda_codec_probe_bus(struct snd_sof_dev *sdev,
                         bool hda_codec_use_common_hdmi);
-void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev);
+void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable);
 void hda_codec_jack_check(struct snd_sof_dev *sdev);
 
 #endif /* CONFIG_SND_SOC_SOF_HDA */
index 31051f2..dc68ed6 100644 (file)
@@ -485,18 +485,9 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
                              const struct audioformat *fmt, int rate)
 {
        struct usb_device *dev = chip->dev;
-       struct usb_host_interface *alts;
-       unsigned int ep;
        unsigned char data[3];
        int err, crate;
 
-       alts = snd_usb_get_host_interface(chip, fmt->iface, fmt->altsetting);
-       if (!alts)
-               return -EINVAL;
-       if (get_iface_desc(alts)->bNumEndpoints < 1)
-               return -EINVAL;
-       ep = get_endpoint(alts, 0)->bEndpointAddress;
-
        /* if endpoint doesn't have sampling rate control, bail out */
        if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
                return 0;
@@ -506,11 +497,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
        data[2] = rate >> 16;
        err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
                              USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
-                             UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
-                             data, sizeof(data));
+                             UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
+                             fmt->endpoint, data, sizeof(data));
        if (err < 0) {
                dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n",
-                       fmt->iface, fmt->altsetting, rate, ep);
+                       fmt->iface, fmt->altsetting, rate, fmt->endpoint);
                return err;
        }
 
@@ -524,11 +515,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
 
        err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
                              USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
-                             UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
-                             data, sizeof(data));
+                             UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
+                             fmt->endpoint, data, sizeof(data));
        if (err < 0) {
                dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",
-                       fmt->iface, fmt->altsetting, ep);
+                       fmt->iface, fmt->altsetting, fmt->endpoint);
                chip->sample_rate_read_error++;
                return 0; /* some devices don't support reading */
        }
index fe73fe3..8e56882 100644 (file)
@@ -1252,6 +1252,15 @@ int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
 
        /* If the interface has been already set up, just set EP parameters */
        if (!ep->iface_ref->need_setup) {
+               /* sample rate setup of UAC1 is per endpoint, and we need
+                * to update at each EP configuration
+                */
+               if (ep->cur_audiofmt->protocol == UAC_VERSION_1) {
+                       err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt,
+                                                      ep->cur_rate);
+                       if (err < 0)
+                               goto unlock;
+               }
                err = snd_usb_endpoint_set_params(chip, ep);
                if (err < 0)
                        goto unlock;
index 1ac2cc6..521cc84 100644 (file)
@@ -175,11 +175,13 @@ static int add_roland_implicit_fb(struct snd_usb_audio *chip,
                                       ifnum, alts);
 }
 
-/* Pioneer devices: playback and capture streams sharing the same iface/altset
+/* Playback and capture EPs on Pioneer devices share the same iface/altset,
+ * but they don't seem working with the implicit fb mode well, hence we
+ * just return as if the sync were already set up.
  */
-static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
-                                  struct audioformat *fmt,
-                                  struct usb_host_interface *alts)
+static int skip_pioneer_sync_ep(struct snd_usb_audio *chip,
+                               struct audioformat *fmt,
+                               struct usb_host_interface *alts)
 {
        struct usb_endpoint_descriptor *epd;
 
@@ -194,8 +196,7 @@ static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
             USB_ENDPOINT_USAGE_IMPLICIT_FB))
                return 0;
-       return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 1,
-                                      alts->desc.bInterfaceNumber, alts);
+       return 1; /* don't handle with the implicit fb, just skip sync EP */
 }
 
 static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
@@ -298,11 +299,11 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
                        return 1;
        }
 
-       /* Pioneer devices implicit feedback with vendor spec class */
+       /* Pioneer devices with vendor spec class */
        if (attr == USB_ENDPOINT_SYNC_ASYNC &&
            alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
            USB_ID_VENDOR(chip->usb_id) == 0x2b73 /* Pioneer */) {
-               if (add_pioneer_implicit_fb(chip, fmt, alts))
+               if (skip_pioneer_sync_ep(chip, fmt, alts))
                        return 1;
        }
 
index 5607990..078bb4c 100644 (file)
@@ -663,7 +663,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
        check_fmts.bits[1] = (u32)(fp->formats >> 32);
        snd_mask_intersect(&check_fmts, fmts);
        if (snd_mask_empty(&check_fmts)) {
-               hwc_debug("   > check: no supported format %d\n", fp->format);
+               hwc_debug("   > check: no supported format 0x%llx\n", fp->formats);
                return 0;
        }
        /* check the channels */
@@ -775,24 +775,11 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
        return apply_hw_params_minmax(it, rmin, rmax);
 }
 
-static int hw_rule_format(struct snd_pcm_hw_params *params,
-                         struct snd_pcm_hw_rule *rule)
+static int apply_hw_params_format_bits(struct snd_mask *fmt, u64 fbits)
 {
-       struct snd_usb_substream *subs = rule->private;
-       const struct audioformat *fp;
-       struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-       u64 fbits;
        u32 oldbits[2];
        int changed;
 
-       hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
-       fbits = 0;
-       list_for_each_entry(fp, &subs->fmt_list, list) {
-               if (!hw_check_valid_format(subs, params, fp))
-                       continue;
-               fbits |= fp->formats;
-       }
-
        oldbits[0] = fmt->bits[0];
        oldbits[1] = fmt->bits[1];
        fmt->bits[0] &= (u32)fbits;
@@ -806,6 +793,24 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
        return changed;
 }
 
+static int hw_rule_format(struct snd_pcm_hw_params *params,
+                         struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       const struct audioformat *fp;
+       struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+       u64 fbits;
+
+       hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
+       fbits = 0;
+       list_for_each_entry(fp, &subs->fmt_list, list) {
+               if (!hw_check_valid_format(subs, params, fp))
+                       continue;
+               fbits |= fp->formats;
+       }
+       return apply_hw_params_format_bits(fmt, fbits);
+}
+
 static int hw_rule_period_time(struct snd_pcm_hw_params *params,
                               struct snd_pcm_hw_rule *rule)
 {
@@ -833,64 +838,92 @@ static int hw_rule_period_time(struct snd_pcm_hw_params *params,
        return apply_hw_params_minmax(it, pmin, UINT_MAX);
 }
 
-/* apply PCM hw constraints from the concurrent sync EP */
-static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
-                                        struct snd_usb_substream *subs)
+/* get the EP or the sync EP for implicit fb when it's already set up */
+static const struct snd_usb_endpoint *
+get_sync_ep_from_substream(struct snd_usb_substream *subs)
 {
        struct snd_usb_audio *chip = subs->stream->chip;
-       struct snd_usb_endpoint *ep;
        const struct audioformat *fp;
-       int err;
+       const struct snd_usb_endpoint *ep;
 
        list_for_each_entry(fp, &subs->fmt_list, list) {
                ep = snd_usb_get_endpoint(chip, fp->endpoint);
                if (ep && ep->cur_rate)
-                       goto found;
+                       return ep;
                if (!fp->implicit_fb)
                        continue;
                /* for the implicit fb, check the sync ep as well */
                ep = snd_usb_get_endpoint(chip, fp->sync_ep);
                if (ep && ep->cur_rate)
-                       goto found;
+                       return ep;
        }
-       return 0;
+       return NULL;
+}
 
- found:
-       if (!find_format(&subs->fmt_list, ep->cur_format, ep->cur_rate,
-                        ep->cur_channels, false, NULL)) {
-               usb_audio_dbg(chip, "EP 0x%x being used, but not applicable\n",
-                             ep->ep_num);
+/* additional hw constraints for implicit feedback mode */
+static int hw_rule_format_implicit_fb(struct snd_pcm_hw_params *params,
+                                     struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       const struct snd_usb_endpoint *ep;
+       struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+
+       ep = get_sync_ep_from_substream(subs);
+       if (!ep)
                return 0;
-       }
 
-       usb_audio_dbg(chip, "EP 0x%x being used, using fixed params:\n",
-                     ep->ep_num);
-       usb_audio_dbg(chip, "rate=%d, period_size=%d, periods=%d\n",
-                     ep->cur_rate, ep->cur_period_frames,
-                     ep->cur_buffer_periods);
+       hwc_debug("applying %s\n", __func__);
+       return apply_hw_params_format_bits(fmt, pcm_format_to_bits(ep->cur_format));
+}
 
-       runtime->hw.formats = subs->formats;
-       runtime->hw.rate_min = runtime->hw.rate_max = ep->cur_rate;
-       runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
-       runtime->hw.periods_min = runtime->hw.periods_max =
-               ep->cur_buffer_periods;
+static int hw_rule_rate_implicit_fb(struct snd_pcm_hw_params *params,
+                                   struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       const struct snd_usb_endpoint *ep;
+       struct snd_interval *it;
 
-       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
-                                 hw_rule_channels, subs,
-                                 SNDRV_PCM_HW_PARAM_FORMAT,
-                                 SNDRV_PCM_HW_PARAM_RATE,
-                                 -1);
-       if (err < 0)
-               return err;
+       ep = get_sync_ep_from_substream(subs);
+       if (!ep)
+               return 0;
 
-       err = snd_pcm_hw_constraint_minmax(runtime,
-                                          SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
-                                          ep->cur_period_frames,
-                                          ep->cur_period_frames);
-       if (err < 0)
-               return err;
+       hwc_debug("applying %s\n", __func__);
+       it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+       return apply_hw_params_minmax(it, ep->cur_rate, ep->cur_rate);
+}
 
-       return 1; /* notify the finding */
+static int hw_rule_period_size_implicit_fb(struct snd_pcm_hw_params *params,
+                                          struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       const struct snd_usb_endpoint *ep;
+       struct snd_interval *it;
+
+       ep = get_sync_ep_from_substream(subs);
+       if (!ep)
+               return 0;
+
+       hwc_debug("applying %s\n", __func__);
+       it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+       return apply_hw_params_minmax(it, ep->cur_period_frames,
+                                     ep->cur_period_frames);
+}
+
+static int hw_rule_periods_implicit_fb(struct snd_pcm_hw_params *params,
+                                      struct snd_pcm_hw_rule *rule)
+{
+       struct snd_usb_substream *subs = rule->private;
+       const struct snd_usb_endpoint *ep;
+       struct snd_interval *it;
+
+       ep = get_sync_ep_from_substream(subs);
+       if (!ep)
+               return 0;
+
+       hwc_debug("applying %s\n", __func__);
+       it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIODS);
+       return apply_hw_params_minmax(it, ep->cur_buffer_periods,
+                                     ep->cur_buffer_periods);
 }
 
 /*
@@ -899,20 +932,11 @@ static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
 
 static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
 {
-       struct snd_usb_audio *chip = subs->stream->chip;
        const struct audioformat *fp;
        unsigned int pt, ptmin;
        int param_period_time_if_needed = -1;
        int err;
 
-       mutex_lock(&chip->mutex);
-       err = apply_hw_constraint_from_sync(runtime, subs);
-       mutex_unlock(&chip->mutex);
-       if (err < 0)
-               return err;
-       if (err > 0) /* found the matching? */
-               goto add_extra_rules;
-
        runtime->hw.formats = subs->formats;
 
        runtime->hw.rate_min = 0x7fffffff;
@@ -957,6 +981,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
 
        err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
                                  hw_rule_rate, subs,
+                                 SNDRV_PCM_HW_PARAM_RATE,
                                  SNDRV_PCM_HW_PARAM_FORMAT,
                                  SNDRV_PCM_HW_PARAM_CHANNELS,
                                  param_period_time_if_needed,
@@ -964,9 +989,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
        if (err < 0)
                return err;
 
-add_extra_rules:
        err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
                                  hw_rule_channels, subs,
+                                 SNDRV_PCM_HW_PARAM_CHANNELS,
                                  SNDRV_PCM_HW_PARAM_FORMAT,
                                  SNDRV_PCM_HW_PARAM_RATE,
                                  param_period_time_if_needed,
@@ -975,6 +1000,7 @@ add_extra_rules:
                return err;
        err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
                                  hw_rule_format, subs,
+                                 SNDRV_PCM_HW_PARAM_FORMAT,
                                  SNDRV_PCM_HW_PARAM_RATE,
                                  SNDRV_PCM_HW_PARAM_CHANNELS,
                                  param_period_time_if_needed,
@@ -993,6 +1019,28 @@ add_extra_rules:
                        return err;
        }
 
+       /* additional hw constraints for implicit fb */
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
+                                 hw_rule_format_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_FORMAT, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+                                 hw_rule_rate_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_RATE, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+                                 hw_rule_period_size_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
+       if (err < 0)
+               return err;
+       err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS,
+                                 hw_rule_periods_implicit_fb, subs,
+                                 SNDRV_PCM_HW_PARAM_PERIODS, -1);
+       if (err < 0)
+               return err;
+
        return 0;
 }
 
index 89e1726..e196e36 100644 (file)
@@ -1470,30 +1470,6 @@ static void set_format_emu_quirk(struct snd_usb_substream *subs,
        subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
 }
 
-
-/*
- * Pioneer DJ DJM-900NXS2
- * Device needs to know the sample rate each time substream is started
- */
-static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs)
-{
-       unsigned int cur_rate = subs->data_endpoint->cur_rate;
-       /* Convert sample rate value to little endian */
-       u8 sr[3];
-
-       sr[0] = cur_rate & 0xff;
-       sr[1] = (cur_rate >> 8) & 0xff;
-       sr[2] = (cur_rate >> 16) & 0xff;
-
-       /* Configure device */
-       usb_set_interface(subs->dev, 0, 1);
-       snd_usb_ctl_msg(subs->stream->chip->dev,
-               usb_rcvctrlpipe(subs->stream->chip->dev, 0),
-               0x01, 0x22, 0x0100, 0x0082, &sr, 0x0003);
-
-       return 0;
-}
-
 void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
                              const struct audioformat *fmt)
 {
@@ -1504,10 +1480,6 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
        case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
                set_format_emu_quirk(subs, fmt);
                break;
-       case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
-       case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
-               pioneer_djm_set_format_quirk(subs);
-               break;
        case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
                subs->stream_offset_adj = 2;
                break;
index cacd66a..a2b233f 100644 (file)
@@ -107,8 +107,8 @@ int monitor_device(const char *device_name,
                        ret = -EIO;
                        break;
                }
-               fprintf(stdout, "GPIO EVENT at %llu on line %d (%d|%d) ",
-                       event.timestamp_ns, event.offset, event.line_seqno,
+               fprintf(stdout, "GPIO EVENT at %" PRIu64 " on line %d (%d|%d) ",
+                       (uint64_t)event.timestamp_ns, event.offset, event.line_seqno,
                        event.seqno);
                switch (event.id) {
                case GPIO_V2_LINE_EVENT_RISING_EDGE:
index f229ec6..41e76d2 100644 (file)
@@ -10,6 +10,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <inttypes.h>
 #include <linux/gpio.h>
 #include <poll.h>
 #include <stdbool.h>
@@ -86,8 +87,8 @@ int main(int argc, char **argv)
                                return EXIT_FAILURE;
                        }
 
-                       printf("line %u: %s at %llu\n",
-                              chg.info.offset, event, chg.timestamp_ns);
+                       printf("line %u: %s at %" PRIu64 "\n",
+                              chg.info.offset, event, (uint64_t)chg.timestamp_ns);
                }
        }
 
index 3c3f2bc..9970a28 100644 (file)
@@ -240,11 +240,6 @@ static int btf_parse_hdr(struct btf *btf)
        }
 
        meta_left = btf->raw_size - sizeof(*hdr);
-       if (!meta_left) {
-               pr_debug("BTF has no data\n");
-               return -EINVAL;
-       }
-
        if (meta_left < hdr->str_off + hdr->str_len) {
                pr_debug("Invalid BTF total size:%u\n", btf->raw_size);
                return -EINVAL;
index cfcdbd7..17465d4 100644 (file)
@@ -367,21 +367,13 @@ static struct perf_mmap* perf_evlist__alloc_mmap(struct perf_evlist *evlist, boo
        return map;
 }
 
-static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
-                                    struct perf_evsel *evsel, int idx, int cpu,
-                                    int thread)
+static void perf_evsel__set_sid_idx(struct perf_evsel *evsel, int idx, int cpu, int thread)
 {
        struct perf_sample_id *sid = SID(evsel, cpu, thread);
 
        sid->idx = idx;
-       if (evlist->cpus && cpu >= 0)
-               sid->cpu = evlist->cpus->map[cpu];
-       else
-               sid->cpu = -1;
-       if (!evsel->system_wide && evlist->threads && thread >= 0)
-               sid->tid = perf_thread_map__pid(evlist->threads, thread);
-       else
-               sid->tid = -1;
+       sid->cpu = perf_cpu_map__cpu(evsel->cpus, cpu);
+       sid->tid = perf_thread_map__pid(evsel->threads, thread);
 }
 
 static struct perf_mmap*
@@ -500,8 +492,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
                        if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
                                                   fd) < 0)
                                return -1;
-                       perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
-                                                thread);
+                       perf_evsel__set_sid_idx(evsel, idx, cpu, thread);
                }
        }
 
index edacfa9..42dad4a 100644 (file)
@@ -186,6 +186,7 @@ struct output_option {
 
 enum {
        OUTPUT_TYPE_SYNTH = PERF_TYPE_MAX,
+       OUTPUT_TYPE_OTHER,
        OUTPUT_TYPE_MAX
 };
 
@@ -283,6 +284,18 @@ static struct {
 
                .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
        },
+
+       [OUTPUT_TYPE_OTHER] = {
+               .user_set = false,
+
+               .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
+                             PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
+                             PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
+                             PERF_OUTPUT_SYM | PERF_OUTPUT_SYMOFFSET |
+                             PERF_OUTPUT_DSO | PERF_OUTPUT_PERIOD,
+
+               .invalid_fields = PERF_OUTPUT_TRACE | PERF_OUTPUT_BPF_OUTPUT,
+       },
 };
 
 struct evsel_script {
@@ -343,8 +356,11 @@ static inline int output_type(unsigned int type)
        case PERF_TYPE_SYNTH:
                return OUTPUT_TYPE_SYNTH;
        default:
-               return type;
+               if (type < PERF_TYPE_MAX)
+                       return type;
        }
+
+       return OUTPUT_TYPE_OTHER;
 }
 
 static inline unsigned int attr_type(unsigned int type)
index ee94d3e..e6d3452 100644 (file)
@@ -162,6 +162,14 @@ static bool contains_event(struct evsel **metric_events, int num_events,
        return false;
 }
 
+static bool evsel_same_pmu(struct evsel *ev1, struct evsel *ev2)
+{
+       if (!ev1->pmu_name || !ev2->pmu_name)
+               return false;
+
+       return !strcmp(ev1->pmu_name, ev2->pmu_name);
+}
+
 /**
  * Find a group of events in perf_evlist that correspond to those from a parsed
  * metric expression. Note, as find_evsel_group is called in the same order as
@@ -280,8 +288,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist,
                         */
                        if (!has_constraint &&
                            ev->leader != metric_events[i]->leader &&
-                           !strcmp(ev->leader->pmu_name,
-                                   metric_events[i]->leader->pmu_name))
+                           evsel_same_pmu(ev->leader, metric_events[i]->leader))
                                break;
                        if (!strcmp(metric_events[i]->name, ev->name)) {
                                set_bit(ev->idx, evlist_used);
@@ -766,7 +773,6 @@ int __weak arch_get_runtimeparam(struct pmu_event *pe __maybe_unused)
 struct metricgroup_add_iter_data {
        struct list_head *metric_list;
        const char *metric;
-       struct metric **m;
        struct expr_ids *ids;
        int *ret;
        bool *has_match;
@@ -1058,12 +1064,13 @@ static int metricgroup__add_metric_sys_event_iter(struct pmu_event *pe,
                                                  void *data)
 {
        struct metricgroup_add_iter_data *d = data;
+       struct metric *m = NULL;
        int ret;
 
        if (!match_pe_metric(pe, d->metric))
                return 0;
 
-       ret = add_metric(d->metric_list, pe, d->metric_no_group, d->m, NULL, d->ids);
+       ret = add_metric(d->metric_list, pe, d->metric_no_group, &m, NULL, d->ids);
        if (ret)
                return ret;
 
@@ -1114,7 +1121,6 @@ static int metricgroup__add_metric(const char *metric, bool metric_no_group,
                                .metric_list = &list,
                                .metric = metric,
                                .metric_no_group = metric_no_group,
-                               .m = &m,
                                .ids = &ids,
                                .has_match = &has_match,
                                .ret = &ret,
index 5390158..09cb3a6 100644 (file)
@@ -1249,6 +1249,8 @@ static void dump_isst_config(int arg)
        isst_ctdp_display_information_end(outf);
 }
 
+static void adjust_scaling_max_from_base_freq(int cpu);
+
 static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
                                  void *arg4)
 {
@@ -1267,6 +1269,9 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
                        int pkg_id = get_physical_package_id(cpu);
                        int die_id = get_physical_die_id(cpu);
 
+                       /* Wait for updated base frequencies */
+                       usleep(2000);
+
                        fprintf(stderr, "Option is set to online/offline\n");
                        ctdp_level.core_cpumask_size =
                                alloc_cpu_set(&ctdp_level.core_cpumask);
@@ -1283,6 +1288,7 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3,
                                        if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) {
                                                fprintf(stderr, "online cpu %d\n", i);
                                                set_cpu_online_offline(i, 1);
+                                               adjust_scaling_max_from_base_freq(i);
                                        } else {
                                                fprintf(stderr, "offline cpu %d\n", i);
                                                set_cpu_online_offline(i, 0);
@@ -1440,6 +1446,31 @@ static int set_cpufreq_scaling_min_max(int cpu, int max, int freq)
        return 0;
 }
 
+static int no_turbo(void)
+{
+       return parse_int_file(0, "/sys/devices/system/cpu/intel_pstate/no_turbo");
+}
+
+static void adjust_scaling_max_from_base_freq(int cpu)
+{
+       int base_freq, scaling_max_freq;
+
+       scaling_max_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu);
+       base_freq = get_cpufreq_base_freq(cpu);
+       if (scaling_max_freq < base_freq || no_turbo())
+               set_cpufreq_scaling_min_max(cpu, 1, base_freq);
+}
+
+static void adjust_scaling_min_from_base_freq(int cpu)
+{
+       int base_freq, scaling_min_freq;
+
+       scaling_min_freq = parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu);
+       base_freq = get_cpufreq_base_freq(cpu);
+       if (scaling_min_freq < base_freq)
+               set_cpufreq_scaling_min_max(cpu, 0, base_freq);
+}
+
 static int set_clx_pbf_cpufreq_scaling_min_max(int cpu)
 {
        struct isst_pkg_ctdp_level_info *ctdp_level;
@@ -1537,6 +1568,7 @@ static void set_scaling_min_to_cpuinfo_max(int cpu)
                        continue;
 
                set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0);
+               adjust_scaling_min_from_base_freq(i);
        }
 }
 
index 21516e2..e808a47 100755 (executable)
@@ -43,9 +43,9 @@ class KunitStatus(Enum):
        BUILD_FAILURE = auto()
        TEST_FAILURE = auto()
 
-def get_kernel_root_path():
-       parts = sys.argv[0] if not __file__ else __file__
-       parts = os.path.realpath(parts).split('tools/testing/kunit')
+def get_kernel_root_path() -> str:
+       path = sys.argv[0] if not __file__ else __file__
+       parts = os.path.realpath(path).split('tools/testing/kunit')
        if len(parts) != 2:
                sys.exit(1)
        return parts[0]
@@ -171,7 +171,7 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
                                exec_result.elapsed_time))
        return parse_result
 
-def add_common_opts(parser):
+def add_common_opts(parser) -> None:
        parser.add_argument('--build_dir',
                            help='As in the make command, it specifies the build '
                            'directory.',
@@ -183,13 +183,13 @@ def add_common_opts(parser):
                            help='Run all KUnit tests through allyesconfig',
                            action='store_true')
 
-def add_build_opts(parser):
+def add_build_opts(parser) -> None:
        parser.add_argument('--jobs',
                            help='As in the make command, "Specifies  the number of '
                            'jobs (commands) to run simultaneously."',
                            type=int, default=8, metavar='jobs')
 
-def add_exec_opts(parser):
+def add_exec_opts(parser) -> None:
        parser.add_argument('--timeout',
                            help='maximum number of seconds to allow for all tests '
                            'to run. This does not include time taken to build the '
@@ -198,7 +198,7 @@ def add_exec_opts(parser):
                            default=300,
                            metavar='timeout')
 
-def add_parse_opts(parser):
+def add_parse_opts(parser) -> None:
        parser.add_argument('--raw_output', help='don\'t format output from kernel',
                            action='store_true')
        parser.add_argument('--json',
@@ -256,10 +256,7 @@ def main(argv, linux=None):
                        os.mkdir(cli_args.build_dir)
 
                if not linux:
-                       linux = kunit_kernel.LinuxSourceTree()
-
-               linux.create_kunitconfig(cli_args.build_dir)
-               linux.read_kunitconfig(cli_args.build_dir)
+                       linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir)
 
                request = KunitRequest(cli_args.raw_output,
                                       cli_args.timeout,
@@ -277,10 +274,7 @@ def main(argv, linux=None):
                        os.mkdir(cli_args.build_dir)
 
                if not linux:
-                       linux = kunit_kernel.LinuxSourceTree()
-
-               linux.create_kunitconfig(cli_args.build_dir)
-               linux.read_kunitconfig(cli_args.build_dir)
+                       linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir)
 
                request = KunitConfigRequest(cli_args.build_dir,
                                             cli_args.make_options)
@@ -292,10 +286,7 @@ def main(argv, linux=None):
                        sys.exit(1)
        elif cli_args.subcommand == 'build':
                if not linux:
-                       linux = kunit_kernel.LinuxSourceTree()
-
-               linux.create_kunitconfig(cli_args.build_dir)
-               linux.read_kunitconfig(cli_args.build_dir)
+                       linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir)
 
                request = KunitBuildRequest(cli_args.jobs,
                                            cli_args.build_dir,
@@ -309,10 +300,7 @@ def main(argv, linux=None):
                        sys.exit(1)
        elif cli_args.subcommand == 'exec':
                if not linux:
-                       linux = kunit_kernel.LinuxSourceTree()
-
-               linux.create_kunitconfig(cli_args.build_dir)
-               linux.read_kunitconfig(cli_args.build_dir)
+                       linux = kunit_kernel.LinuxSourceTree(cli_args.build_dir)
 
                exec_request = KunitExecRequest(cli_args.timeout,
                                                cli_args.build_dir,
index 02ffc3a..bdd6023 100644 (file)
@@ -8,6 +8,7 @@
 
 import collections
 import re
+from typing import List, Set
 
 CONFIG_IS_NOT_SET_PATTERN = r'^# CONFIG_(\w+) is not set$'
 CONFIG_PATTERN = r'^CONFIG_(\w+)=(\S+|".*")$'
@@ -30,10 +31,10 @@ class KconfigParseError(Exception):
 class Kconfig(object):
        """Represents defconfig or .config specified using the Kconfig language."""
 
-       def __init__(self):
-               self._entries = []
+       def __init__(self) -> None:
+               self._entries = []  # type: List[KconfigEntry]
 
-       def entries(self):
+       def entries(self) -> Set[KconfigEntry]:
                return set(self._entries)
 
        def add_entry(self, entry: KconfigEntry) -> None:
index 624b31b..f5cca5c 100644 (file)
@@ -13,7 +13,7 @@ import kunit_parser
 
 from kunit_parser import TestStatus
 
-def get_json_result(test_result, def_config, build_dir, json_path):
+def get_json_result(test_result, def_config, build_dir, json_path) -> str:
        sub_groups = []
 
        # Each test suite is mapped to a KernelCI sub_group
index 698358c..2076a5a 100644 (file)
@@ -11,6 +11,7 @@ import subprocess
 import os
 import shutil
 import signal
+from typing import Iterator
 
 from contextlib import ExitStack
 
@@ -39,7 +40,7 @@ class BuildError(Exception):
 class LinuxSourceTreeOperations(object):
        """An abstraction over command line operations performed on a source tree."""
 
-       def make_mrproper(self):
+       def make_mrproper(self) -> None:
                try:
                        subprocess.check_output(['make', 'mrproper'], stderr=subprocess.STDOUT)
                except OSError as e:
@@ -47,7 +48,7 @@ class LinuxSourceTreeOperations(object):
                except subprocess.CalledProcessError as e:
                        raise ConfigError(e.output.decode())
 
-       def make_olddefconfig(self, build_dir, make_options):
+       def make_olddefconfig(self, build_dir, make_options) -> None:
                command = ['make', 'ARCH=um', 'olddefconfig']
                if make_options:
                        command.extend(make_options)
@@ -60,7 +61,7 @@ class LinuxSourceTreeOperations(object):
                except subprocess.CalledProcessError as e:
                        raise ConfigError(e.output.decode())
 
-       def make_allyesconfig(self, build_dir, make_options):
+       def make_allyesconfig(self, build_dir, make_options) -> None:
                kunit_parser.print_with_timestamp(
                        'Enabling all CONFIGs for UML...')
                command = ['make', 'ARCH=um', 'allyesconfig']
@@ -82,7 +83,7 @@ class LinuxSourceTreeOperations(object):
                kunit_parser.print_with_timestamp(
                        'Starting Kernel with all configs takes a few minutes...')
 
-       def make(self, jobs, build_dir, make_options):
+       def make(self, jobs, build_dir, make_options) -> None:
                command = ['make', 'ARCH=um', '--jobs=' + str(jobs)]
                if make_options:
                        command.extend(make_options)
@@ -100,7 +101,7 @@ class LinuxSourceTreeOperations(object):
                if stderr:  # likely only due to build warnings
                        print(stderr.decode())
 
-       def linux_bin(self, params, timeout, build_dir):
+       def linux_bin(self, params, timeout, build_dir) -> None:
                """Runs the Linux UML binary. Must be named 'linux'."""
                linux_bin = get_file_path(build_dir, 'linux')
                outfile = get_outfile_path(build_dir)
@@ -110,41 +111,42 @@ class LinuxSourceTreeOperations(object):
                                                   stderr=subprocess.STDOUT)
                        process.wait(timeout)
 
-def get_kconfig_path(build_dir):
+def get_kconfig_path(build_dir) -> str:
        return get_file_path(build_dir, KCONFIG_PATH)
 
-def get_kunitconfig_path(build_dir):
+def get_kunitconfig_path(build_dir) -> str:
        return get_file_path(build_dir, KUNITCONFIG_PATH)
 
-def get_outfile_path(build_dir):
+def get_outfile_path(build_dir) -> str:
        return get_file_path(build_dir, OUTFILE_PATH)
 
 class LinuxSourceTree(object):
        """Represents a Linux kernel source tree with KUnit tests."""
 
-       def __init__(self):
-               self._ops = LinuxSourceTreeOperations()
+       def __init__(self, build_dir: str, load_config=True, defconfig=DEFAULT_KUNITCONFIG_PATH) -> None:
                signal.signal(signal.SIGINT, self.signal_handler)
 
-       def clean(self):
-               try:
-                       self._ops.make_mrproper()
-               except ConfigError as e:
-                       logging.error(e)
-                       return False
-               return True
+               self._ops = LinuxSourceTreeOperations()
+
+               if not load_config:
+                       return
 
-       def create_kunitconfig(self, build_dir, defconfig=DEFAULT_KUNITCONFIG_PATH):
                kunitconfig_path = get_kunitconfig_path(build_dir)
                if not os.path.exists(kunitconfig_path):
                        shutil.copyfile(defconfig, kunitconfig_path)
 
-       def read_kunitconfig(self, build_dir):
-               kunitconfig_path = get_kunitconfig_path(build_dir)
                self._kconfig = kunit_config.Kconfig()
                self._kconfig.read_from_file(kunitconfig_path)
 
-       def validate_config(self, build_dir):
+       def clean(self) -> bool:
+               try:
+                       self._ops.make_mrproper()
+               except ConfigError as e:
+                       logging.error(e)
+                       return False
+               return True
+
+       def validate_config(self, build_dir) -> bool:
                kconfig_path = get_kconfig_path(build_dir)
                validated_kconfig = kunit_config.Kconfig()
                validated_kconfig.read_from_file(kconfig_path)
@@ -158,7 +160,7 @@ class LinuxSourceTree(object):
                        return False
                return True
 
-       def build_config(self, build_dir, make_options):
+       def build_config(self, build_dir, make_options) -> bool:
                kconfig_path = get_kconfig_path(build_dir)
                if build_dir and not os.path.exists(build_dir):
                        os.mkdir(build_dir)
@@ -170,7 +172,7 @@ class LinuxSourceTree(object):
                        return False
                return self.validate_config(build_dir)
 
-       def build_reconfig(self, build_dir, make_options):
+       def build_reconfig(self, build_dir, make_options) -> bool:
                """Creates a new .config if it is not a subset of the .kunitconfig."""
                kconfig_path = get_kconfig_path(build_dir)
                if os.path.exists(kconfig_path):
@@ -186,7 +188,7 @@ class LinuxSourceTree(object):
                        print('Generating .config ...')
                        return self.build_config(build_dir, make_options)
 
-       def build_um_kernel(self, alltests, jobs, build_dir, make_options):
+       def build_um_kernel(self, alltests, jobs, build_dir, make_options) -> bool:
                try:
                        if alltests:
                                self._ops.make_allyesconfig(build_dir, make_options)
@@ -197,7 +199,7 @@ class LinuxSourceTree(object):
                        return False
                return self.validate_config(build_dir)
 
-       def run_kernel(self, args=[], build_dir='', timeout=None):
+       def run_kernel(self, args=[], build_dir='', timeout=None) -> Iterator[str]:
                args.extend(['mem=1G', 'console=tty'])
                self._ops.linux_bin(args, timeout, build_dir)
                outfile = get_outfile_path(build_dir)
@@ -206,6 +208,6 @@ class LinuxSourceTree(object):
                        for line in file:
                                yield line
 
-       def signal_handler(self, sig, frame):
+       def signal_handler(self, sig, frame) -> None:
                logging.error('Build interruption occurred. Cleaning console.')
                subprocess.call(['stty', 'sane'])
index 6614ec4..e8bcc13 100644 (file)
@@ -12,32 +12,32 @@ from collections import namedtuple
 from datetime import datetime
 from enum import Enum, auto
 from functools import reduce
-from typing import List, Optional, Tuple
+from typing import Iterable, Iterator, List, Optional, Tuple
 
 TestResult = namedtuple('TestResult', ['status','suites','log'])
 
 class TestSuite(object):
-       def __init__(self):
-               self.status = None
-               self.name = None
-               self.cases = []
+       def __init__(self) -> None:
+               self.status = TestStatus.SUCCESS
+               self.name = ''
+               self.cases = []  # type: List[TestCase]
 
-       def __str__(self):
-               return 'TestSuite(' + self.status + ',' + self.name + ',' + str(self.cases) + ')'
+       def __str__(self) -> str:
+               return 'TestSuite(' + str(self.status) + ',' + self.name + ',' + str(self.cases) + ')'
 
-       def __repr__(self):
+       def __repr__(self) -> str:
                return str(self)
 
 class TestCase(object):
-       def __init__(self):
-               self.status = None
+       def __init__(self) -> None:
+               self.status = TestStatus.SUCCESS
                self.name = ''
-               self.log = []
+               self.log = []  # type: List[str]
 
-       def __str__(self):
-               return 'TestCase(' + self.status + ',' + self.name + ',' + str(self.log) + ')'
+       def __str__(self) -> str:
+               return 'TestCase(' + str(self.status) + ',' + self.name + ',' + str(self.log) + ')'
 
-       def __repr__(self):
+       def __repr__(self) -> str:
                return str(self)
 
 class TestStatus(Enum):
@@ -51,7 +51,7 @@ kunit_start_re = re.compile(r'TAP version [0-9]+$')
 kunit_end_re = re.compile('(List of all partitions:|'
                          'Kernel panic - not syncing: VFS:)')
 
-def isolate_kunit_output(kernel_output):
+def isolate_kunit_output(kernel_output) -> Iterator[str]:
        started = False
        for line in kernel_output:
                line = line.rstrip()  # line always has a trailing \n
@@ -64,7 +64,7 @@ def isolate_kunit_output(kernel_output):
                elif started:
                        yield line[prefix_len:] if prefix_len > 0 else line
 
-def raw_output(kernel_output):
+def raw_output(kernel_output) -> None:
        for line in kernel_output:
                print(line.rstrip())
 
@@ -72,36 +72,36 @@ DIVIDER = '=' * 60
 
 RESET = '\033[0;0m'
 
-def red(text):
+def red(text) -> str:
        return '\033[1;31m' + text + RESET
 
-def yellow(text):
+def yellow(text) -> str:
        return '\033[1;33m' + text + RESET
 
-def green(text):
+def green(text) -> str:
        return '\033[1;32m' + text + RESET
 
-def print_with_timestamp(message):
+def print_with_timestamp(message) -> None:
        print('[%s] %s' % (datetime.now().strftime('%H:%M:%S'), message))
 
-def format_suite_divider(message):
+def format_suite_divider(message) -> str:
        return '======== ' + message + ' ========'
 
-def print_suite_divider(message):
+def print_suite_divider(message) -> None:
        print_with_timestamp(DIVIDER)
        print_with_timestamp(format_suite_divider(message))
 
-def print_log(log):
+def print_log(log) -> None:
        for m in log:
                print_with_timestamp(m)
 
 TAP_ENTRIES = re.compile(r'^(TAP|[\s]*ok|[\s]*not ok|[\s]*[0-9]+\.\.[0-9]+|[\s]*#).*$')
 
-def consume_non_diagnositic(lines: List[str]) -> None:
+def consume_non_diagnostic(lines: List[str]) -> None:
        while lines and not TAP_ENTRIES.match(lines[0]):
                lines.pop(0)
 
-def save_non_diagnositic(lines: List[str], test_case: TestCase) -> None:
+def save_non_diagnostic(lines: List[str], test_case: TestCase) -> None:
        while lines and not TAP_ENTRIES.match(lines[0]):
                test_case.log.append(lines[0])
                lines.pop(0)
@@ -113,7 +113,7 @@ OK_NOT_OK_SUBTEST = re.compile(r'^[\s]+(ok|not ok) [0-9]+ - (.*)$')
 OK_NOT_OK_MODULE = re.compile(r'^(ok|not ok) ([0-9]+) - (.*)$')
 
 def parse_ok_not_ok_test_case(lines: List[str], test_case: TestCase) -> bool:
-       save_non_diagnositic(lines, test_case)
+       save_non_diagnostic(lines, test_case)
        if not lines:
                test_case.status = TestStatus.TEST_CRASHED
                return True
@@ -139,7 +139,7 @@ SUBTEST_DIAGNOSTIC = re.compile(r'^[\s]+# (.*)$')
 DIAGNOSTIC_CRASH_MESSAGE = re.compile(r'^[\s]+# .*?: kunit test case crashed!$')
 
 def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool:
-       save_non_diagnositic(lines, test_case)
+       save_non_diagnostic(lines, test_case)
        if not lines:
                return False
        line = lines[0]
@@ -155,7 +155,7 @@ def parse_diagnostic(lines: List[str], test_case: TestCase) -> bool:
 
 def parse_test_case(lines: List[str]) -> Optional[TestCase]:
        test_case = TestCase()
-       save_non_diagnositic(lines, test_case)
+       save_non_diagnostic(lines, test_case)
        while parse_diagnostic(lines, test_case):
                pass
        if parse_ok_not_ok_test_case(lines, test_case):
@@ -166,7 +166,7 @@ def parse_test_case(lines: List[str]) -> Optional[TestCase]:
 SUBTEST_HEADER = re.compile(r'^[\s]+# Subtest: (.*)$')
 
 def parse_subtest_header(lines: List[str]) -> Optional[str]:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        if not lines:
                return None
        match = SUBTEST_HEADER.match(lines[0])
@@ -179,7 +179,7 @@ def parse_subtest_header(lines: List[str]) -> Optional[str]:
 SUBTEST_PLAN = re.compile(r'[\s]+[0-9]+\.\.([0-9]+)')
 
 def parse_subtest_plan(lines: List[str]) -> Optional[int]:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        match = SUBTEST_PLAN.match(lines[0])
        if match:
                lines.pop(0)
@@ -202,7 +202,7 @@ def max_status(left: TestStatus, right: TestStatus) -> TestStatus:
 def parse_ok_not_ok_test_suite(lines: List[str],
                               test_suite: TestSuite,
                               expected_suite_index: int) -> bool:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        if not lines:
                test_suite.status = TestStatus.TEST_CRASHED
                return False
@@ -224,18 +224,17 @@ def parse_ok_not_ok_test_suite(lines: List[str],
        else:
                return False
 
-def bubble_up_errors(to_status, status_container_list) -> TestStatus:
-       status_list = map(to_status, status_container_list)
-       return reduce(max_status, status_list, TestStatus.SUCCESS)
+def bubble_up_errors(statuses: Iterable[TestStatus]) -> TestStatus:
+       return reduce(max_status, statuses, TestStatus.SUCCESS)
 
 def bubble_up_test_case_errors(test_suite: TestSuite) -> TestStatus:
-       max_test_case_status = bubble_up_errors(lambda x: x.status, test_suite.cases)
+       max_test_case_status = bubble_up_errors(x.status for x in test_suite.cases)
        return max_status(max_test_case_status, test_suite.status)
 
 def parse_test_suite(lines: List[str], expected_suite_index: int) -> Optional[TestSuite]:
        if not lines:
                return None
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        test_suite = TestSuite()
        test_suite.status = TestStatus.SUCCESS
        name = parse_subtest_header(lines)
@@ -264,7 +263,7 @@ def parse_test_suite(lines: List[str], expected_suite_index: int) -> Optional[Te
 TAP_HEADER = re.compile(r'^TAP version 14$')
 
 def parse_tap_header(lines: List[str]) -> bool:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        if TAP_HEADER.match(lines[0]):
                lines.pop(0)
                return True
@@ -274,7 +273,7 @@ def parse_tap_header(lines: List[str]) -> bool:
 TEST_PLAN = re.compile(r'[0-9]+\.\.([0-9]+)')
 
 def parse_test_plan(lines: List[str]) -> Optional[int]:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        match = TEST_PLAN.match(lines[0])
        if match:
                lines.pop(0)
@@ -282,11 +281,11 @@ def parse_test_plan(lines: List[str]) -> Optional[int]:
        else:
                return None
 
-def bubble_up_suite_errors(test_suite_list: List[TestSuite]) -> TestStatus:
-       return bubble_up_errors(lambda x: x.status, test_suite_list)
+def bubble_up_suite_errors(test_suites: Iterable[TestSuite]) -> TestStatus:
+       return bubble_up_errors(x.status for x in test_suites)
 
 def parse_test_result(lines: List[str]) -> TestResult:
-       consume_non_diagnositic(lines)
+       consume_non_diagnostic(lines)
        if not lines or not parse_tap_header(lines):
                return TestResult(TestStatus.NO_TESTS, [], lines)
        expected_test_suite_num = parse_test_plan(lines)
index c0fe73a..3bfcf00 100644 (file)
@@ -34,61 +34,6 @@ struct storage {
        struct bpf_spin_lock lock;
 };
 
-/* Copies an rm binary to a temp file. dest is a mkstemp template */
-static int copy_rm(char *dest)
-{
-       int fd_in, fd_out = -1, ret = 0;
-       struct stat stat;
-       char *buf = NULL;
-
-       fd_in = open("/bin/rm", O_RDONLY);
-       if (fd_in < 0)
-               return -errno;
-
-       fd_out = mkstemp(dest);
-       if (fd_out < 0) {
-               ret = -errno;
-               goto out;
-       }
-
-       ret = fstat(fd_in, &stat);
-       if (ret == -1) {
-               ret = -errno;
-               goto out;
-       }
-
-       buf = malloc(stat.st_blksize);
-       if (!buf) {
-               ret = -errno;
-               goto out;
-       }
-
-       while (ret = read(fd_in, buf, stat.st_blksize), ret > 0) {
-               ret = write(fd_out, buf, ret);
-               if (ret < 0) {
-                       ret = -errno;
-                       goto out;
-
-               }
-       }
-       if (ret < 0) {
-               ret = -errno;
-               goto out;
-
-       }
-
-       /* Set executable permission on the copied file */
-       ret = chmod(dest, 0100);
-       if (ret == -1)
-               ret = -errno;
-
-out:
-       free(buf);
-       close(fd_in);
-       close(fd_out);
-       return ret;
-}
-
 /* Fork and exec the provided rm binary and return the exit code of the
  * forked process and its pid.
  */
@@ -168,9 +113,11 @@ static bool check_syscall_operations(int map_fd, int obj_fd)
 
 void test_test_local_storage(void)
 {
-       char tmp_exec_path[PATH_MAX] = "/tmp/copy_of_rmXXXXXX";
+       char tmp_dir_path[64] = "/tmp/local_storageXXXXXX";
        int err, serv_sk = -1, task_fd = -1, rm_fd = -1;
        struct local_storage *skel = NULL;
+       char tmp_exec_path[64];
+       char cmd[256];
 
        skel = local_storage__open_and_load();
        if (CHECK(!skel, "skel_load", "lsm skeleton failed\n"))
@@ -189,18 +136,24 @@ void test_test_local_storage(void)
                                      task_fd))
                goto close_prog;
 
-       err = copy_rm(tmp_exec_path);
-       if (CHECK(err < 0, "copy_rm", "err %d errno %d\n", err, errno))
+       if (CHECK(!mkdtemp(tmp_dir_path), "mkdtemp",
+                 "unable to create tmpdir: %d\n", errno))
                goto close_prog;
 
+       snprintf(tmp_exec_path, sizeof(tmp_exec_path), "%s/copy_of_rm",
+                tmp_dir_path);
+       snprintf(cmd, sizeof(cmd), "cp /bin/rm %s", tmp_exec_path);
+       if (CHECK_FAIL(system(cmd)))
+               goto close_prog_rmdir;
+
        rm_fd = open(tmp_exec_path, O_RDONLY);
        if (CHECK(rm_fd < 0, "open", "failed to open %s err:%d, errno:%d",
                  tmp_exec_path, rm_fd, errno))
-               goto close_prog;
+               goto close_prog_rmdir;
 
        if (!check_syscall_operations(bpf_map__fd(skel->maps.inode_storage_map),
                                      rm_fd))
-               goto close_prog;
+               goto close_prog_rmdir;
 
        /* Sets skel->bss->monitored_pid to the pid of the forked child
         * forks a child process that executes tmp_exec_path and tries to
@@ -209,33 +162,36 @@ void test_test_local_storage(void)
         */
        err = run_self_unlink(&skel->bss->monitored_pid, tmp_exec_path);
        if (CHECK(err != EPERM, "run_self_unlink", "err %d want EPERM\n", err))
-               goto close_prog_unlink;
+               goto close_prog_rmdir;
 
        /* Set the process being monitored to be the current process */
        skel->bss->monitored_pid = getpid();
 
-       /* Remove the temporary created executable */
-       err = unlink(tmp_exec_path);
-       if (CHECK(err != 0, "unlink", "unable to unlink %s: %d", tmp_exec_path,
-                 errno))
-               goto close_prog_unlink;
+       /* Move copy_of_rm to a new location so that it triggers the
+        * inode_rename LSM hook with a new_dentry that has a NULL inode ptr.
+        */
+       snprintf(cmd, sizeof(cmd), "mv %s/copy_of_rm %s/check_null_ptr",
+                tmp_dir_path, tmp_dir_path);
+       if (CHECK_FAIL(system(cmd)))
+               goto close_prog_rmdir;
 
        CHECK(skel->data->inode_storage_result != 0, "inode_storage_result",
              "inode_local_storage not set\n");
 
        serv_sk = start_server(AF_INET6, SOCK_STREAM, NULL, 0, 0);
        if (CHECK(serv_sk < 0, "start_server", "failed to start server\n"))
-               goto close_prog;
+               goto close_prog_rmdir;
 
        CHECK(skel->data->sk_storage_result != 0, "sk_storage_result",
              "sk_local_storage not set\n");
 
        if (!check_syscall_operations(bpf_map__fd(skel->maps.sk_storage_map),
                                      serv_sk))
-               goto close_prog;
+               goto close_prog_rmdir;
 
-close_prog_unlink:
-       unlink(tmp_exec_path);
+close_prog_rmdir:
+       snprintf(cmd, sizeof(cmd), "rm -rf %s", tmp_dir_path);
+       system(cmd);
 close_prog:
        close(serv_sk);
        close(rm_fd);
index 3e3de13..95868bc 100644 (file)
@@ -50,7 +50,6 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim)
        __u32 pid = bpf_get_current_pid_tgid() >> 32;
        struct local_storage *storage;
        bool is_self_unlink;
-       int err;
 
        if (pid != monitored_pid)
                return 0;
@@ -66,8 +65,27 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim)
                        return -EPERM;
        }
 
-       storage = bpf_inode_storage_get(&inode_storage_map, victim->d_inode, 0,
-                                       BPF_LOCAL_STORAGE_GET_F_CREATE);
+       return 0;
+}
+
+SEC("lsm/inode_rename")
+int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry,
+            struct inode *new_dir, struct dentry *new_dentry,
+            unsigned int flags)
+{
+       __u32 pid = bpf_get_current_pid_tgid() >> 32;
+       struct local_storage *storage;
+       int err;
+
+       /* new_dentry->d_inode can be NULL when the inode is renamed to a file
+        * that did not exist before. The helper should be able to handle this
+        * NULL pointer.
+        */
+       bpf_inode_storage_get(&inode_storage_map, new_dentry->d_inode, 0,
+                             BPF_LOCAL_STORAGE_GET_F_CREATE);
+
+       storage = bpf_inode_storage_get(&inode_storage_map, old_dentry->d_inode,
+                                       0, 0);
        if (!storage)
                return 0;
 
@@ -76,7 +94,7 @@ int BPF_PROG(unlink_hook, struct inode *dir, struct dentry *victim)
                inode_storage_result = -1;
        bpf_spin_unlock(&storage->lock);
 
-       err = bpf_inode_storage_delete(&inode_storage_map, victim->d_inode);
+       err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode);
        if (!err)
                inode_storage_result = err;
 
@@ -133,37 +151,18 @@ int BPF_PROG(socket_post_create, struct socket *sock, int family, int type,
        return 0;
 }
 
-SEC("lsm/file_open")
-int BPF_PROG(file_open, struct file *file)
-{
-       __u32 pid = bpf_get_current_pid_tgid() >> 32;
-       struct local_storage *storage;
-
-       if (pid != monitored_pid)
-               return 0;
-
-       if (!file->f_inode)
-               return 0;
-
-       storage = bpf_inode_storage_get(&inode_storage_map, file->f_inode, 0,
-                                       BPF_LOCAL_STORAGE_GET_F_CREATE);
-       if (!storage)
-               return 0;
-
-       bpf_spin_lock(&storage->lock);
-       storage->value = DUMMY_STORAGE_VALUE;
-       bpf_spin_unlock(&storage->lock);
-       return 0;
-}
-
 /* This uses the local storage to remember the inode of the binary that a
  * process was originally executing.
  */
 SEC("lsm/bprm_committed_creds")
 void BPF_PROG(exec, struct linux_binprm *bprm)
 {
+       __u32 pid = bpf_get_current_pid_tgid() >> 32;
        struct local_storage *storage;
 
+       if (pid != monitored_pid)
+               return;
+
        storage = bpf_task_storage_get(&task_storage_map,
                                       bpf_get_current_task_btf(), 0,
                                       BPF_LOCAL_STORAGE_GET_F_CREATE);
@@ -172,4 +171,13 @@ void BPF_PROG(exec, struct linux_binprm *bprm)
                storage->exec_inode = bprm->file->f_inode;
                bpf_spin_unlock(&storage->lock);
        }
+
+       storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode,
+                                       0, BPF_LOCAL_STORAGE_GET_F_CREATE);
+       if (!storage)
+               return;
+
+       bpf_spin_lock(&storage->lock);
+       storage->value = DUMMY_STORAGE_VALUE;
+       bpf_spin_unlock(&storage->lock);
 }
index 777a814..f8569f0 100644 (file)
@@ -50,7 +50,7 @@
 #define MAX_INSNS      BPF_MAXINSNS
 #define MAX_TEST_INSNS 1000000
 #define MAX_FIXUPS     8
-#define MAX_NR_MAPS    20
+#define MAX_NR_MAPS    21
 #define MAX_TEST_RUNS  8
 #define POINTER_VALUE  0xcafe4all
 #define TEST_DATA_LEN  64
@@ -87,6 +87,7 @@ struct bpf_test {
        int fixup_sk_storage_map[MAX_FIXUPS];
        int fixup_map_event_output[MAX_FIXUPS];
        int fixup_map_reuseport_array[MAX_FIXUPS];
+       int fixup_map_ringbuf[MAX_FIXUPS];
        const char *errstr;
        const char *errstr_unpriv;
        uint32_t insn_processed;
@@ -640,6 +641,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
        int *fixup_sk_storage_map = test->fixup_sk_storage_map;
        int *fixup_map_event_output = test->fixup_map_event_output;
        int *fixup_map_reuseport_array = test->fixup_map_reuseport_array;
+       int *fixup_map_ringbuf = test->fixup_map_ringbuf;
 
        if (test->fill_helper) {
                test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn));
@@ -817,6 +819,14 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
                        fixup_map_reuseport_array++;
                } while (*fixup_map_reuseport_array);
        }
+       if (*fixup_map_ringbuf) {
+               map_fds[20] = create_map(BPF_MAP_TYPE_RINGBUF, 0,
+                                          0, 4096);
+               do {
+                       prog[*fixup_map_ringbuf].imm = map_fds[20];
+                       fixup_map_ringbuf++;
+               } while (*fixup_map_ringbuf);
+       }
 }
 
 struct libcap {
index 45d43bf..0b94389 100644 (file)
        .result = ACCEPT,
        .result_unpriv = ACCEPT,
 },
+{
+       "check valid spill/fill, ptr to mem",
+       .insns = {
+       /* reserve 8 byte ringbuf memory */
+       BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
+       BPF_LD_MAP_FD(BPF_REG_1, 0),
+       BPF_MOV64_IMM(BPF_REG_2, 8),
+       BPF_MOV64_IMM(BPF_REG_3, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
+       /* store a pointer to the reserved memory in R6 */
+       BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
+       /* check whether the reservation was successful */
+       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
+       /* spill R6(mem) into the stack */
+       BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
+       /* fill it back in R7 */
+       BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8),
+       /* should be able to access *(R7) = 0 */
+       BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0),
+       /* submit the reserved ringbuf memory */
+       BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
+       BPF_MOV64_IMM(BPF_REG_2, 0),
+       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
+       BPF_MOV64_IMM(BPF_REG_0, 0),
+       BPF_EXIT_INSN(),
+       },
+       .fixup_map_ringbuf = { 1 },
+       .result = ACCEPT,
+       .result_unpriv = ACCEPT,
+},
 {
        "check corrupted spill/fill",
        .insns = {
index 84205c3..2b57077 100755 (executable)
@@ -1055,7 +1055,6 @@ ipv6_addr_metric_test()
 
        check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260"
        log_test $? 0 "Set metric with peer route on local side"
-       log_test $? 0 "User specified metric on local address"
        check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260"
        log_test $? 0 "Set metric with peer route on peer side"