Merge tag 'mtd/fixes-for-4.20-rc5' of git://git.infradead.org/linux-mtd
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 20:18:00 +0000 (12:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 30 Nov 2018 20:18:00 +0000 (12:18 -0800)
Pull mtd fixes from Boris Brezillon:
 "NAND fix:
   - Fix BBT cache allocation done in nanddev_bbt_init()

  SPI NOR fixes:
   - Fix the erase type selection logic"

* tag 'mtd/fixes-for-4.20-rc5' of git://git.infradead.org/linux-mtd:
  mtd: nand: Fix memory allocation in nanddev_bbt_init()
  mtd: spi-nor: fix erase_type array to indicate current map conf

240 files changed:
Documentation/admin-guide/kernel-parameters.txt
Documentation/devicetree/bindings/spi/spi-uniphier.txt
Documentation/x86/boot.txt
MAINTAINERS
arch/arm/kernel/ftrace.c
arch/arm64/kernel/ftrace.c
arch/arm64/net/bpf_jit_comp.c
arch/ia64/include/asm/numa.h
arch/ia64/kernel/acpi.c
arch/ia64/mm/numa.c
arch/microblaze/kernel/ftrace.c
arch/mips/kernel/ftrace.c
arch/nds32/kernel/ftrace.c
arch/parisc/kernel/ftrace.c
arch/powerpc/kernel/trace/ftrace.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/net/bpf_jit_comp64.c
arch/riscv/kernel/ftrace.c
arch/s390/kernel/ftrace.c
arch/s390/kernel/perf_cpum_cf.c
arch/s390/mm/pgalloc.c
arch/sh/kernel/ftrace.c
arch/sparc/kernel/ftrace.c
arch/sparc/net/bpf_jit_comp_64.c
arch/x86/boot/header.S
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/perf_event.h
arch/x86/include/asm/fpu/internal.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/x86_init.h
arch/x86/include/uapi/asm/bootparam.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/cpu/mcheck/mce_amd.c
arch/x86/kernel/fpu/signal.c
arch/x86/kernel/ftrace.c
arch/x86/kernel/head32.c
arch/x86/kernel/head64.c
arch/x86/kernel/setup.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/xtensa/kernel/asm-offsets.c
arch/xtensa/kernel/process.c
arch/xtensa/kernel/ptrace.c
drivers/acpi/acpica/exserial.c
drivers/atm/firestream.c
drivers/firmware/efi/efi.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/ast/ast_main.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/drm_auth.c
drivers/gpu/drm/i915/gvt/aperture_gm.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/mmio_context.c
drivers/gpu/drm/meson/meson_crtc.c
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/meson/meson_venc.c
drivers/gpu/drm/meson/meson_viu.c
drivers/gpu/drm/rcar-du/rcar_du_group.c
drivers/hwmon/ina2xx.c
drivers/hwmon/mlxreg-fan.c
drivers/hwmon/raspberrypi-hwmon.c
drivers/hwmon/w83795.c
drivers/infiniband/core/roce_gid_mgmt.c
drivers/infiniband/core/umem_odp.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/hns/hns_roce_hw_v2.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/odp.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/sw/rdmavt/ah.c
drivers/infiniband/sw/rdmavt/ah.h
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/net/ethernet/cavium/thunder/nic_main.c
drivers/net/ethernet/hisilicon/hip04_eth.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_xsk.c
drivers/net/ethernet/intel/igb/e1000_i210.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
drivers/net/ethernet/microchip/lan743x_main.c
drivers/net/ethernet/microchip/lan743x_main.h
drivers/net/ethernet/qlogic/qed/qed_debug.c
drivers/net/ethernet/via/via-velocity.c
drivers/net/phy/phy_device.c
drivers/net/rionet.c
drivers/net/usb/ipheth.c
drivers/opp/of.c
drivers/opp/ti-opp-supply.c
drivers/s390/cio/vfio_ccw_cp.c
drivers/s390/cio/vfio_ccw_drv.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_queue.c
drivers/s390/crypto/zcrypt_cex2a.c
drivers/s390/crypto/zcrypt_cex2c.c
drivers/s390/crypto/zcrypt_cex4.c
drivers/s390/net/qeth_core_main.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-omap2-mcspi.c
fs/afs/dir.c
fs/afs/fs_probe.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/misc.c
fs/afs/rotate.c
fs/afs/vl_probe.c
fs/afs/vl_rotate.c
fs/aio.c
fs/btrfs/disk-io.c
fs/btrfs/file.c
fs/btrfs/qgroup.c
fs/btrfs/relocation.c
fs/btrfs/send.c
fs/btrfs/super.c
fs/exportfs/expfs.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/pstore/ram.c
fs/sysv/inode.c
fs/udf/super.c
fs/udf/unicode.c
include/linux/filter.h
include/linux/ftrace.h
include/linux/mlx5/mlx5_ifc.h
include/linux/netfilter/nf_conntrack_proto_gre.h
include/linux/pstore.h
include/linux/sched.h
include/linux/tracehook.h
include/linux/tracepoint.h
include/net/netfilter/ipv4/nf_nat_masquerade.h
include/net/netfilter/ipv6/nf_nat_masquerade.h
include/sound/soc.h
include/trace/events/sched.h
kernel/bpf/core.c
kernel/bpf/local_storage.c
kernel/bpf/queue_stack_maps.c
kernel/bpf/verifier.c
kernel/events/uprobes.c
kernel/trace/bpf_trace.c
kernel/trace/ftrace.c
kernel/trace/trace.h
kernel/trace/trace_functions_graph.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_sched_wakeup.c
lib/iov_iter.c
lib/test_hexdump.c
net/core/filter.c
net/ipv4/ip_output.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
net/ipv4/netfilter/nft_masq_ipv4.c
net/ipv4/tcp_input.c
net/ipv4/tcp_timer.c
net/ipv6/ip6_output.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6t_MASQUERADE.c
net/ipv6/netfilter/nf_nat_masquerade_ipv6.c
net/ipv6/netfilter/nft_masq_ipv6.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/nf_conncount.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_tables_api.c
net/netfilter/nfnetlink_cttimeout.c
net/netfilter/nft_compat.c
net/netfilter/nft_flow_offload.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_hashlimit.c
net/sctp/output.c
net/tipc/node.c
security/selinux/nlmsgtab.c
sound/core/control.c
sound/isa/wss/wss_lib.c
sound/pci/ac97/ac97_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/pcm186x.h
sound/soc/codecs/pcm3060.c
sound/soc/codecs/wm_adsp.c
sound/soc/intel/Kconfig
sound/soc/intel/boards/Kconfig
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/skylake/skl.c
sound/soc/omap/omap-abe-twl6040.c
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-mcpdm.c
sound/soc/qcom/common.c
sound/soc/qcom/qdsp6/q6afe-dai.c
sound/soc/qcom/qdsp6/q6afe.c
sound/soc/qcom/qdsp6/q6asm-dai.c
sound/soc/qcom/qdsp6/q6routing.c
sound/soc/rockchip/rockchip_pcm.c
sound/soc/sh/rcar/ssi.c
sound/soc/soc-acpi.c
sound/soc/soc-core.c
sound/soc/stm/stm32_sai_sub.c
sound/soc/sunxi/Kconfig
sound/soc/sunxi/sun8i-codec.c
sound/sparc/cs4231.c
sound/usb/quirks-table.h
tools/arch/x86/include/asm/cpufeatures.h
tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
tools/bpf/bpftool/Documentation/bpftool-map.rst
tools/bpf/bpftool/Documentation/bpftool-net.rst
tools/bpf/bpftool/Documentation/bpftool-perf.rst
tools/bpf/bpftool/Documentation/bpftool-prog.rst
tools/bpf/bpftool/Documentation/bpftool.rst
tools/bpf/bpftool/common.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/prog.c
tools/build/Makefile.feature
tools/build/feature/Makefile
tools/build/feature/test-all.c
tools/build/feature/test-get_current_dir_name.c [new file with mode: 0644]
tools/include/uapi/asm-generic/ioctls.h
tools/include/uapi/drm/i915_drm.h
tools/include/uapi/linux/pkt_cls.h [new file with mode: 0644]
tools/include/uapi/linux/tc_act/tc_bpf.h [new file with mode: 0644]
tools/objtool/elf.c
tools/perf/Makefile.config
tools/perf/tests/attr/base-record
tools/perf/trace/beauty/ioctl.c
tools/perf/util/Build
tools/perf/util/evsel.c
tools/perf/util/get_current_dir_name.c [new file with mode: 0644]
tools/perf/util/namespaces.c
tools/perf/util/namespaces.h
tools/perf/util/util.h
tools/testing/selftests/Makefile
tools/testing/selftests/bpf/test_netcnt.c
tools/testing/selftests/bpf/test_verifier.c
tools/testing/selftests/netfilter/Makefile [new file with mode: 0644]
tools/testing/selftests/netfilter/config [new file with mode: 0644]
tools/testing/selftests/netfilter/nft_trans_stress.sh [new file with mode: 0755]

index 19f4423e70d913ea2bf0801e4e14b57dc74e320f..675170c360788638cb6021a3e1f04bbc94cefef0 100644 (file)
                        causing system reset or hang due to sending
                        INIT from AP to BSP.
 
-       disable_counter_freezing [HW]
+       perf_v4_pmi=    [X86,INTEL]
+                       Format: <bool>
                        Disable Intel PMU counter freezing feature.
                        The feature only exists starting from
                        Arch Perfmon v4 (Skylake and newer).
index 504a4ecfc7b16869192c666e903a9d884d9f052d..b04e66a52de5dfc4ca66a3efc5339e4986275033 100644 (file)
@@ -5,18 +5,20 @@ UniPhier SoCs have SCSSI which supports SPI single channel.
 Required properties:
  - compatible: should be "socionext,uniphier-scssi"
  - reg: address and length of the spi master registers
- - #address-cells: must be <1>, see spi-bus.txt
- - #size-cells: must be <0>, see spi-bus.txt
- - clocks: A phandle to the clock for the device.
- - resets: A phandle to the reset control for the device.
+ - interrupts: a single interrupt specifier
+ - pinctrl-names: should be "default"
+ - pinctrl-0: pin control state for the default mode
+ - clocks: a phandle to the clock for the device
+ - resets: a phandle to the reset control for the device
 
 Example:
 
 spi0: spi@54006000 {
        compatible = "socionext,uniphier-scssi";
        reg = <0x54006000 0x100>;
-       #address-cells = <1>;
-       #size-cells = <0>;
+       interrupts = <0 39 4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi0>;
        clocks = <&peri_clk 11>;
        resets = <&peri_rst 11>;
 };
index 7727db8f94bce6af42b5cc1920bf2a46798ad0b4..5e9b826b5f62fd1cf8dfcae07fc5bde66594428b 100644 (file)
@@ -61,18 +61,6 @@ Protocol 2.12:       (Kernel 3.8) Added the xloadflags field and extension fields
                to struct boot_params for loading bzImage and ramdisk
                above 4G in 64bit.
 
-Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in
-               xloadflags to support booting a 64-bit kernel from 32-bit
-               EFI
-
-Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical
-               address of the ACPI RSDP table.
-               The bootloader updates version with:
-               0x8000 | min(kernel-version, bootloader-version)
-               kernel-version being the protocol version supported by
-               the kernel and bootloader-version the protocol version
-               supported by the bootloader.
-
 **** MEMORY LAYOUT
 
 The traditional memory map for the kernel loader, used for Image or
@@ -209,7 +197,6 @@ Offset      Proto   Name            Meaning
 0258/8 2.10+   pref_address    Preferred loading address
 0260/4 2.10+   init_size       Linear memory required during initialization
 0264/4 2.11+   handover_offset Offset of handover entry point
-0268/8 2.14+   acpi_rsdp_addr  Physical address of RSDP table
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
@@ -322,7 +309,7 @@ Protocol:   2.00+
   Contains the magic number "HdrS" (0x53726448).
 
 Field name:    version
-Type:          modify
+Type:          read
 Offset/size:   0x206/2
 Protocol:      2.00+
 
@@ -330,12 +317,6 @@ Protocol:  2.00+
   e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
   10.17.
 
-  Up to protocol version 2.13 this information is only read by the
-  bootloader. From protocol version 2.14 onwards the bootloader will
-  write the used protocol version or-ed with 0x8000 to the field. The
-  used protocol version will be the minimum of the supported protocol
-  versions of the bootloader and the kernel.
-
 Field name:    realmode_swtch
 Type:          modify (optional)
 Offset/size:   0x208/4
@@ -763,17 +744,6 @@ Offset/size:       0x264/4
 
   See EFI HANDOVER PROTOCOL below for more details.
 
-Field name:    acpi_rsdp_addr
-Type:          write
-Offset/size:   0x268/8
-Protocol:      2.14+
-
-  This field can be set by the boot loader to tell the kernel the
-  physical address of the ACPI RSDP table.
-
-  A value of 0 indicates the kernel should fall back to the standard
-  methods to locate the RSDP.
-
 
 **** THE IMAGE CHECKSUM
 
index 380e43f585d3416bbc1e24f0240a9852eafce597..5d17f568a3b9730a0dc4ff40e2179a6e1af09c7a 100644 (file)
@@ -2801,7 +2801,7 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
 Q:     https://patchwork.ozlabs.org/project/netdev/list/?delegate=77147
 S:     Supported
-F:     arch/x86/net/bpf_jit*
+F:     arch/*/net/*
 F:     Documentation/networking/filter.txt
 F:     Documentation/bpf/
 F:     include/linux/bpf*
@@ -2821,6 +2821,67 @@ F:       tools/bpf/
 F:     tools/lib/bpf/
 F:     tools/testing/selftests/bpf/
 
+BPF JIT for ARM
+M:     Shubham Bansal <illusionist.neo@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/arm/net/
+
+BPF JIT for ARM64
+M:     Daniel Borkmann <daniel@iogearbox.net>
+M:     Alexei Starovoitov <ast@kernel.org>
+M:     Zi Shen Lim <zlim.lnx@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     arch/arm64/net/
+
+BPF JIT for MIPS (32-BIT AND 64-BIT)
+M:     Paul Burton <paul.burton@mips.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/mips/net/
+
+BPF JIT for NFP NICs
+M:     Jakub Kicinski <jakub.kicinski@netronome.com>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     drivers/net/ethernet/netronome/nfp/bpf/
+
+BPF JIT for POWERPC (32-BIT AND 64-BIT)
+M:     Naveen N. Rao <naveen.n.rao@linux.ibm.com>
+M:     Sandipan Das <sandipan@linux.ibm.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/powerpc/net/
+
+BPF JIT for S390
+M:     Martin Schwidefsky <schwidefsky@de.ibm.com>
+M:     Heiko Carstens <heiko.carstens@de.ibm.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/s390/net/
+X:     arch/s390/net/pnet.c
+
+BPF JIT for SPARC (32-BIT AND 64-BIT)
+M:     David S. Miller <davem@davemloft.net>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/sparc/net/
+
+BPF JIT for X86 32-BIT
+M:     Wang YanQing <udknight@gmail.com>
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     arch/x86/net/bpf_jit_comp32.c
+
+BPF JIT for X86 64-BIT
+M:     Alexei Starovoitov <ast@kernel.org>
+M:     Daniel Borkmann <daniel@iogearbox.net>
+L:     netdev@vger.kernel.org
+S:     Supported
+F:     arch/x86/net/
+X:     arch/x86/net/bpf_jit_comp32.c
+
 BROADCOM B44 10/100 ETHERNET DRIVER
 M:     Michael Chan <michael.chan@broadcom.com>
 L:     netdev@vger.kernel.org
@@ -13949,6 +14010,7 @@ S:      Supported
 F:     Documentation/devicetree/bindings/sound/
 F:     Documentation/sound/soc/
 F:     sound/soc/
+F:     include/dt-bindings/sound/
 F:     include/sound/soc*
 
 SOUNDWIRE SUBSYSTEM
index 0142fcfcc3d3732a6add6132f352bd0dccd036c8..bda949fd84e8b60b13ee3c79f5a28ad7e5151369 100644 (file)
@@ -183,9 +183,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
                           unsigned long frame_pointer)
 {
        unsigned long return_hooker = (unsigned long) &return_to_handler;
-       struct ftrace_graph_ent trace;
        unsigned long old;
-       int err;
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
@@ -193,21 +191,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
        old = *parent;
        *parent = return_hooker;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
+       if (function_graph_enter(old, self_addr, frame_pointer, NULL))
                *parent = old;
-               return;
-       }
-
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                      frame_pointer, NULL);
-       if (err == -EBUSY) {
-               *parent = old;
-               return;
-       }
 }
 
 #ifdef CONFIG_DYNAMIC_FTRACE
index 50986e388d2b27e92f6984914af4ce756ea0ee46..57e962290df3a0aee4aaeddbb6a8c9369b5c7931 100644 (file)
@@ -216,8 +216,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 {
        unsigned long return_hooker = (unsigned long)&return_to_handler;
        unsigned long old;
-       struct ftrace_graph_ent trace;
-       int err;
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
@@ -229,18 +227,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
         */
        old = *parent;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
-               return;
-
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                      frame_pointer, NULL);
-       if (err == -EBUSY)
-               return;
-       else
+       if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
                *parent = return_hooker;
 }
 
index a6fdaea07c6339cf2754d582765747ee5d8b2ff5..89198017e8e681268504235331471b38b7e945b9 100644 (file)
@@ -351,7 +351,8 @@ static void build_epilogue(struct jit_ctx *ctx)
  * >0 - successfully JITed a 16-byte eBPF instruction.
  * <0 - failed to JIT.
  */
-static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
+static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
+                     bool extra_pass)
 {
        const u8 code = insn->code;
        const u8 dst = bpf2a64[insn->dst_reg];
@@ -625,12 +626,19 @@ emit_cond_jmp:
        case BPF_JMP | BPF_CALL:
        {
                const u8 r0 = bpf2a64[BPF_REG_0];
-               const u64 func = (u64)__bpf_call_base + imm;
+               bool func_addr_fixed;
+               u64 func_addr;
+               int ret;
 
-               if (ctx->prog->is_func)
-                       emit_addr_mov_i64(tmp, func, ctx);
+               ret = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass,
+                                           &func_addr, &func_addr_fixed);
+               if (ret < 0)
+                       return ret;
+               if (func_addr_fixed)
+                       /* We can use optimized emission here. */
+                       emit_a64_mov_i64(tmp, func_addr, ctx);
                else
-                       emit_a64_mov_i64(tmp, func, ctx);
+                       emit_addr_mov_i64(tmp, func_addr, ctx);
                emit(A64_BLR(tmp), ctx);
                emit(A64_MOV(1, r0, A64_R(0)), ctx);
                break;
@@ -753,7 +761,7 @@ emit_cond_jmp:
        return 0;
 }
 
-static int build_body(struct jit_ctx *ctx)
+static int build_body(struct jit_ctx *ctx, bool extra_pass)
 {
        const struct bpf_prog *prog = ctx->prog;
        int i;
@@ -762,7 +770,7 @@ static int build_body(struct jit_ctx *ctx)
                const struct bpf_insn *insn = &prog->insnsi[i];
                int ret;
 
-               ret = build_insn(insn, ctx);
+               ret = build_insn(insn, ctx, extra_pass);
                if (ret > 0) {
                        i++;
                        if (ctx->image == NULL)
@@ -858,7 +866,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        /* 1. Initial fake pass to compute ctx->idx. */
 
        /* Fake pass to fill in ctx->offset. */
-       if (build_body(&ctx)) {
+       if (build_body(&ctx, extra_pass)) {
                prog = orig_prog;
                goto out_off;
        }
@@ -888,7 +896,7 @@ skip_init_ctx:
 
        build_prologue(&ctx, was_classic);
 
-       if (build_body(&ctx)) {
+       if (build_body(&ctx, extra_pass)) {
                bpf_jit_binary_free(header);
                prog = orig_prog;
                goto out_off;
index ebef7f40aabbe26a5fa384294bf05819f949dd30..c5c253cb9bd63ad85177e3e0f00321385362da7e 100644 (file)
@@ -59,7 +59,9 @@ extern struct node_cpuid_s node_cpuid[NR_CPUS];
  */
 
 extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
-#define node_distance(from,to) (numa_slit[(from) * MAX_NUMNODES + (to)])
+#define slit_distance(from,to) (numa_slit[(from) * MAX_NUMNODES + (to)])
+extern int __node_distance(int from, int to);
+#define node_distance(from,to) __node_distance(from, to)
 
 extern int paddr_to_nid(unsigned long paddr);
 
index 1dacbf5e9e09a5a71f9e21bd5fd88eed8199e823..41eb281709da1c334226fc652d7184888e48d327 100644 (file)
@@ -578,8 +578,8 @@ void __init acpi_numa_fixup(void)
        if (!slit_table) {
                for (i = 0; i < MAX_NUMNODES; i++)
                        for (j = 0; j < MAX_NUMNODES; j++)
-                               node_distance(i, j) = i == j ? LOCAL_DISTANCE :
-                                                       REMOTE_DISTANCE;
+                               slit_distance(i, j) = i == j ?
+                                       LOCAL_DISTANCE : REMOTE_DISTANCE;
                return;
        }
 
@@ -592,7 +592,7 @@ void __init acpi_numa_fixup(void)
                        if (!pxm_bit_test(j))
                                continue;
                        node_to = pxm_to_node(j);
-                       node_distance(node_from, node_to) =
+                       slit_distance(node_from, node_to) =
                            slit_table->entry[i * slit_table->locality_count + j];
                }
        }
index 3861d6e32d5ff910615305ef691b4a30fd1028f2..a03803506b0c041fde49ca23bfae160ba6499bd9 100644 (file)
@@ -36,6 +36,12 @@ struct node_cpuid_s node_cpuid[NR_CPUS] =
  */
 u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
 
+int __node_distance(int from, int to)
+{
+       return slit_distance(from, to);
+}
+EXPORT_SYMBOL(__node_distance);
+
 /* Identify which cnode a physical address resides on */
 int
 paddr_to_nid(unsigned long paddr)
index d57563c58a26be43672098d9895d9107c945e8d8..224eea40e1ee805fa15d56f33e16b248fbaec30a 100644 (file)
@@ -22,8 +22,7 @@
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 {
        unsigned long old;
-       int faulted, err;
-       struct ftrace_graph_ent trace;
+       int faulted;
        unsigned long return_hooker = (unsigned long)
                                &return_to_handler;
 
@@ -63,18 +62,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                return;
        }
 
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0, NULL);
-       if (err == -EBUSY) {
+       if (function_graph_enter(old, self_addr, 0, NULL))
                *parent = old;
-               return;
-       }
-
-       trace.func = self_addr;
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
-               current->curr_ret_stack--;
-               *parent = old;
-       }
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
index 7f3dfdbc3657e6705b6a797c6e1dfa565fa3bff9..b122cbb4aad184c5dddd56d4990c7924ed9ad563 100644 (file)
@@ -322,7 +322,6 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
                           unsigned long fp)
 {
        unsigned long old_parent_ra;
-       struct ftrace_graph_ent trace;
        unsigned long return_hooker = (unsigned long)
            &return_to_handler;
        int faulted, insns;
@@ -369,12 +368,6 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
        if (unlikely(faulted))
                goto out;
 
-       if (ftrace_push_return_trace(old_parent_ra, self_ra, &trace.depth, fp,
-                                    NULL) == -EBUSY) {
-               *parent_ra_addr = old_parent_ra;
-               return;
-       }
-
        /*
         * Get the recorded ip of the current mcount calling site in the
         * __mcount_loc section, which will be used to filter the function
@@ -382,13 +375,10 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
         */
 
        insns = core_kernel_text(self_ra) ? 2 : MCOUNT_OFFSET_INSNS + 1;
-       trace.func = self_ra - (MCOUNT_INSN_SIZE * insns);
+       self_ra -= (MCOUNT_INSN_SIZE * insns);
 
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
-               current->curr_ret_stack--;
+       if (function_graph_enter(old_parent_ra, self_ra, fp, NULL))
                *parent_ra_addr = old_parent_ra;
-       }
        return;
 out:
        ftrace_graph_stop();
index a0a9679ad5dee8a9d08810556cc204dedd127c08..8a41372551ff3cbca4bcf0a94e1bea400dcb4c01 100644 (file)
@@ -211,29 +211,15 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
                           unsigned long frame_pointer)
 {
        unsigned long return_hooker = (unsigned long)&return_to_handler;
-       struct ftrace_graph_ent trace;
        unsigned long old;
-       int err;
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
 
        old = *parent;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
-               return;
-
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                      frame_pointer, NULL);
-
-       if (err == -EBUSY)
-               return;
-
-       *parent = return_hooker;
+       if (!function_graph_enter(old, self_addr, frame_pointer, NULL))
+               *parent = return_hooker;
 }
 
 noinline void ftrace_graph_caller(void)
index 6fa8535d3cceb55de7ecf1051fcb2c812dcb1f51..e46a4157a8948862697755439496a16e5acb29f4 100644 (file)
@@ -30,7 +30,6 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
                                        unsigned long self_addr)
 {
        unsigned long old;
-       struct ftrace_graph_ent trace;
        extern int parisc_return_to_handler;
 
        if (unlikely(ftrace_graph_is_dead()))
@@ -41,19 +40,9 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
 
        old = *parent;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
-               return;
-
-        if (ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                    0, NULL) == -EBUSY)
-                return;
-
-       /* activate parisc_return_to_handler() as return point */
-       *parent = (unsigned long) &parisc_return_to_handler;
+       if (!function_graph_enter(old, self_addr, 0, NULL))
+               /* activate parisc_return_to_handler() as return point */
+               *parent = (unsigned long) &parisc_return_to_handler;
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
index 4bf051d3e21e70a61f51136c63c22c1c03c9faae..b65c8a34ad6efb718da71a2556e2db9db6bb7cf2 100644 (file)
@@ -950,7 +950,6 @@ int ftrace_disable_ftrace_graph_caller(void)
  */
 unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
 {
-       struct ftrace_graph_ent trace;
        unsigned long return_hooker;
 
        if (unlikely(ftrace_graph_is_dead()))
@@ -961,18 +960,8 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
 
        return_hooker = ppc_function_entry(return_to_handler);
 
-       trace.func = ip;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
-               goto out;
-
-       if (ftrace_push_return_trace(parent, ip, &trace.depth, 0,
-                                    NULL) == -EBUSY)
-               goto out;
-
-       parent = return_hooker;
+       if (!function_graph_enter(parent, ip, 0, NULL))
+               parent = return_hooker;
 out:
        return parent;
 }
index d65b961661fbf6d9075b34c523269bb1261845fe..a56f8413758ab1d796328093eb754d3b6715f4eb 100644 (file)
@@ -983,6 +983,7 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
                ret = kvmhv_enter_nested_guest(vcpu);
                if (ret == H_INTERRUPT) {
                        kvmppc_set_gpr(vcpu, 3, 0);
+                       vcpu->arch.hcall_needed = 0;
                        return -EINTR;
                }
                break;
index 50b129785aeeead06f8d131a64d30a6ccda2576e..17482f5de3e262f53d67b4199490660362b394a0 100644 (file)
@@ -166,7 +166,33 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
        PPC_BLR();
 }
 
-static void bpf_jit_emit_func_call(u32 *image, struct codegen_context *ctx, u64 func)
+static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx,
+                                      u64 func)
+{
+#ifdef PPC64_ELF_ABI_v1
+       /* func points to the function descriptor */
+       PPC_LI64(b2p[TMP_REG_2], func);
+       /* Load actual entry point from function descriptor */
+       PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_2], 0);
+       /* ... and move it to LR */
+       PPC_MTLR(b2p[TMP_REG_1]);
+       /*
+        * Load TOC from function descriptor at offset 8.
+        * We can clobber r2 since we get called through a
+        * function pointer (so caller will save/restore r2)
+        * and since we don't use a TOC ourself.
+        */
+       PPC_BPF_LL(2, b2p[TMP_REG_2], 8);
+#else
+       /* We can clobber r12 */
+       PPC_FUNC_ADDR(12, func);
+       PPC_MTLR(12);
+#endif
+       PPC_BLRL();
+}
+
+static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx,
+                                      u64 func)
 {
        unsigned int i, ctx_idx = ctx->idx;
 
@@ -273,7 +299,7 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
 {
        const struct bpf_insn *insn = fp->insnsi;
        int flen = fp->len;
-       int i;
+       int i, ret;
 
        /* Start of epilogue code - will only be valid 2nd pass onwards */
        u32 exit_addr = addrs[flen];
@@ -284,8 +310,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
                u32 src_reg = b2p[insn[i].src_reg];
                s16 off = insn[i].off;
                s32 imm = insn[i].imm;
+               bool func_addr_fixed;
+               u64 func_addr;
                u64 imm64;
-               u8 *func;
                u32 true_cond;
                u32 tmp_idx;
 
@@ -711,23 +738,15 @@ emit_clear:
                case BPF_JMP | BPF_CALL:
                        ctx->seen |= SEEN_FUNC;
 
-                       /* bpf function call */
-                       if (insn[i].src_reg == BPF_PSEUDO_CALL)
-                               if (!extra_pass)
-                                       func = NULL;
-                               else if (fp->aux->func && off < fp->aux->func_cnt)
-                                       /* use the subprog id from the off
-                                        * field to lookup the callee address
-                                        */
-                                       func = (u8 *) fp->aux->func[off]->bpf_func;
-                               else
-                                       return -EINVAL;
-                       /* kernel helper call */
-                       else
-                               func = (u8 *) __bpf_call_base + imm;
-
-                       bpf_jit_emit_func_call(image, ctx, (u64)func);
+                       ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass,
+                                                   &func_addr, &func_addr_fixed);
+                       if (ret < 0)
+                               return ret;
 
+                       if (func_addr_fixed)
+                               bpf_jit_emit_func_call_hlp(image, ctx, func_addr);
+                       else
+                               bpf_jit_emit_func_call_rel(image, ctx, func_addr);
                        /* move return value from r3 to BPF_REG_0 */
                        PPC_MR(b2p[BPF_REG_0], 3);
                        break;
index 1157b6b52d259fa79edf0d44f589022174aff18c..c433f6d3dd64f0b4eec0a567854d1cfca59c650f 100644 (file)
@@ -132,7 +132,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 {
        unsigned long return_hooker = (unsigned long)&return_to_handler;
        unsigned long old;
-       struct ftrace_graph_ent trace;
        int err;
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
@@ -144,17 +143,8 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
         */
        old = *parent;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       if (!ftrace_graph_entry(&trace))
-               return;
-
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                      frame_pointer, parent);
-       if (err == -EBUSY)
-               return;
-       *parent = return_hooker;
+       if (function_graph_enter(old, self_addr, frame_pointer, parent))
+               *parent = return_hooker;
 }
 
 #ifdef CONFIG_DYNAMIC_FTRACE
index 84be7f02d0c2157029cb2868231b67c7603bbf42..39b13d71a8fe6dc2979e8a8320ae62b675b8ee9b 100644 (file)
@@ -203,22 +203,13 @@ device_initcall(ftrace_plt_init);
  */
 unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
 {
-       struct ftrace_graph_ent trace;
-
        if (unlikely(ftrace_graph_is_dead()))
                goto out;
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                goto out;
        ip -= MCOUNT_INSN_SIZE;
-       trace.func = ip;
-       trace.depth = current->curr_ret_stack + 1;
-       /* Only trace if the calling function expects to. */
-       if (!ftrace_graph_entry(&trace))
-               goto out;
-       if (ftrace_push_return_trace(parent, ip, &trace.depth, 0,
-                                    NULL) == -EBUSY)
-               goto out;
-       parent = (unsigned long) return_to_handler;
+       if (!function_graph_enter(parent, ip, 0, NULL))
+               parent = (unsigned long) return_to_handler;
 out:
        return parent;
 }
index 74091fd3101e9122943b9155572a1c46d2bf9858..d5523adeddbf4dc0d9b92962bb39328d474cba22 100644 (file)
@@ -346,6 +346,8 @@ static int __hw_perf_event_init(struct perf_event *event)
                break;
 
        case PERF_TYPE_HARDWARE:
+               if (is_sampling_event(event))   /* No sampling support */
+                       return -ENOENT;
                ev = attr->config;
                /* Count user space (problem-state) only */
                if (!attr->exclude_user && attr->exclude_kernel) {
index 814f26520aa2c2439de4e10ce52bf0476c8f2661..6791562779eeca0f6eb6559336a19329de72faff 100644 (file)
@@ -131,6 +131,7 @@ void crst_table_downgrade(struct mm_struct *mm)
        }
 
        pgd = mm->pgd;
+       mm_dec_nr_pmds(mm);
        mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
        mm->context.asce_limit = _REGION3_SIZE;
        mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
index 96dd9f7da2506d061fa499c5992a8e7eb4a426bf..1b04270e5460e8d77decb68a5c15f329227706ea 100644 (file)
@@ -321,8 +321,7 @@ int ftrace_disable_ftrace_graph_caller(void)
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 {
        unsigned long old;
-       int faulted, err;
-       struct ftrace_graph_ent trace;
+       int faulted;
        unsigned long return_hooker = (unsigned long)&return_to_handler;
 
        if (unlikely(ftrace_graph_is_dead()))
@@ -365,18 +364,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                return;
        }
 
-       err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0, NULL);
-       if (err == -EBUSY) {
+       if (function_graph_enter(old, self_addr, 0, NULL))
                __raw_writel(old, parent);
-               return;
-       }
-
-       trace.func = self_addr;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
-               current->curr_ret_stack--;
-               __raw_writel(old, parent);
-       }
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
index 915dda4ae41205ca51d5aa0d8ac4ee4c777ba3e8..684b84ce397f711c8ebf7857d9f4c826d4eb09ca 100644 (file)
@@ -126,20 +126,11 @@ unsigned long prepare_ftrace_return(unsigned long parent,
                                    unsigned long frame_pointer)
 {
        unsigned long return_hooker = (unsigned long) &return_to_handler;
-       struct ftrace_graph_ent trace;
 
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return parent + 8UL;
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace))
-               return parent + 8UL;
-
-       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
-                                    frame_pointer, NULL) == -EBUSY)
+       if (function_graph_enter(parent, self_addr, frame_pointer, NULL))
                return parent + 8UL;
 
        return return_hooker;
index 222785af550b46736676808b6e00d8d8cef9a286..5fda4f7bf15d176fbb913435ea0a25c510c8df5a 100644 (file)
@@ -791,7 +791,7 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src,
 }
 
 /* Just skip the save instruction and the ctx register move.  */
-#define BPF_TAILCALL_PROLOGUE_SKIP     16
+#define BPF_TAILCALL_PROLOGUE_SKIP     32
 #define BPF_TAILCALL_CNT_SP_OFF                (STACK_BIAS + 128)
 
 static void build_prologue(struct jit_ctx *ctx)
@@ -824,9 +824,15 @@ static void build_prologue(struct jit_ctx *ctx)
                const u8 vfp = bpf2sparc[BPF_REG_FP];
 
                emit(ADD | IMMED | RS1(FP) | S13(STACK_BIAS) | RD(vfp), ctx);
+       } else {
+               emit_nop(ctx);
        }
 
        emit_reg_move(I0, O0, ctx);
+       emit_reg_move(I1, O1, ctx);
+       emit_reg_move(I2, O2, ctx);
+       emit_reg_move(I3, O3, ctx);
+       emit_reg_move(I4, O4, ctx);
        /* If you add anything here, adjust BPF_TAILCALL_PROLOGUE_SKIP above. */
 }
 
@@ -1270,6 +1276,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                u32 opcode = 0, rs2;
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_2_used = true;
                emit_loadimm(imm, tmp2, ctx);
 
@@ -1308,6 +1317,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp = bpf2sparc[TMP_REG_1];
                u32 opcode = 0, rs2;
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                switch (BPF_SIZE(code)) {
                case BPF_W:
                        opcode = ST32;
@@ -1340,6 +1352,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                const u8 tmp3 = bpf2sparc[TMP_REG_3];
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_1_used = true;
                ctx->tmp_2_used = true;
                ctx->tmp_3_used = true;
@@ -1360,6 +1375,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
                const u8 tmp2 = bpf2sparc[TMP_REG_2];
                const u8 tmp3 = bpf2sparc[TMP_REG_3];
 
+               if (insn->dst_reg == BPF_REG_FP)
+                       ctx->saw_frame_pointer = true;
+
                ctx->tmp_1_used = true;
                ctx->tmp_2_used = true;
                ctx->tmp_3_used = true;
@@ -1425,12 +1443,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        struct bpf_prog *tmp, *orig_prog = prog;
        struct sparc64_jit_data *jit_data;
        struct bpf_binary_header *header;
+       u32 prev_image_size, image_size;
        bool tmp_blinded = false;
        bool extra_pass = false;
        struct jit_ctx ctx;
-       u32 image_size;
        u8 *image_ptr;
-       int pass;
+       int pass, i;
 
        if (!prog->jit_requested)
                return orig_prog;
@@ -1461,61 +1479,82 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
                header = jit_data->header;
                extra_pass = true;
                image_size = sizeof(u32) * ctx.idx;
+               prev_image_size = image_size;
+               pass = 1;
                goto skip_init_ctx;
        }
 
        memset(&ctx, 0, sizeof(ctx));
        ctx.prog = prog;
 
-       ctx.offset = kcalloc(prog->len, sizeof(unsigned int), GFP_KERNEL);
+       ctx.offset = kmalloc_array(prog->len, sizeof(unsigned int), GFP_KERNEL);
        if (ctx.offset == NULL) {
                prog = orig_prog;
                goto out_off;
        }
 
-       /* Fake pass to detect features used, and get an accurate assessment
-        * of what the final image size will be.
+       /* Longest sequence emitted is for bswap32, 12 instructions.  Pre-cook
+        * the offset array so that we converge faster.
         */
-       if (build_body(&ctx)) {
-               prog = orig_prog;
-               goto out_off;
-       }
-       build_prologue(&ctx);
-       build_epilogue(&ctx);
-
-       /* Now we know the actual image size. */
-       image_size = sizeof(u32) * ctx.idx;
-       header = bpf_jit_binary_alloc(image_size, &image_ptr,
-                                     sizeof(u32), jit_fill_hole);
-       if (header == NULL) {
-               prog = orig_prog;
-               goto out_off;
-       }
+       for (i = 0; i < prog->len; i++)
+               ctx.offset[i] = i * (12 * 4);
 
-       ctx.image = (u32 *)image_ptr;
-skip_init_ctx:
-       for (pass = 1; pass < 3; pass++) {
+       prev_image_size = ~0U;
+       for (pass = 1; pass < 40; pass++) {
                ctx.idx = 0;
 
                build_prologue(&ctx);
-
                if (build_body(&ctx)) {
-                       bpf_jit_binary_free(header);
                        prog = orig_prog;
                        goto out_off;
                }
-
                build_epilogue(&ctx);
 
                if (bpf_jit_enable > 1)
-                       pr_info("Pass %d: shrink = %d, seen = [%c%c%c%c%c%c]\n", pass,
-                               image_size - (ctx.idx * 4),
+                       pr_info("Pass %d: size = %u, seen = [%c%c%c%c%c%c]\n", pass,
+                               ctx.idx * 4,
                                ctx.tmp_1_used ? '1' : ' ',
                                ctx.tmp_2_used ? '2' : ' ',
                                ctx.tmp_3_used ? '3' : ' ',
                                ctx.saw_frame_pointer ? 'F' : ' ',
                                ctx.saw_call ? 'C' : ' ',
                                ctx.saw_tail_call ? 'T' : ' ');
+
+               if (ctx.idx * 4 == prev_image_size)
+                       break;
+               prev_image_size = ctx.idx * 4;
+               cond_resched();
+       }
+
+       /* Now we know the actual image size. */
+       image_size = sizeof(u32) * ctx.idx;
+       header = bpf_jit_binary_alloc(image_size, &image_ptr,
+                                     sizeof(u32), jit_fill_hole);
+       if (header == NULL) {
+               prog = orig_prog;
+               goto out_off;
+       }
+
+       ctx.image = (u32 *)image_ptr;
+skip_init_ctx:
+       ctx.idx = 0;
+
+       build_prologue(&ctx);
+
+       if (build_body(&ctx)) {
+               bpf_jit_binary_free(header);
+               prog = orig_prog;
+               goto out_off;
+       }
+
+       build_epilogue(&ctx);
+
+       if (ctx.idx * 4 != prev_image_size) {
+               pr_err("bpf_jit: Failed to converge, prev_size=%u size=%d\n",
+                      prev_image_size, ctx.idx * 4);
+               bpf_jit_binary_free(header);
+               prog = orig_prog;
+               goto out_off;
        }
 
        if (bpf_jit_enable > 1)
index 4c881c850125c674145e4627078c91ce4a453f0e..850b8762e889656c43da518520c5bae60e945e3d 100644 (file)
@@ -300,7 +300,7 @@ _start:
        # Part 2 of the header, from the old setup.S
 
                .ascii  "HdrS"          # header signature
-               .word   0x020e          # header version number (>= 0x0105)
+               .word   0x020d          # header version number (>= 0x0105)
                                        # or else old loadlin-1.5 will fail)
                .globl realmode_swtch
 realmode_swtch:        .word   0, 0            # default_switch, SETUPSEG
@@ -558,10 +558,6 @@ pref_address:              .quad LOAD_PHYSICAL_ADDR        # preferred load addr
 init_size:             .long INIT_SIZE         # kernel initialization size
 handover_offset:       .long 0                 # Filled in by build.c
 
-acpi_rsdp_addr:                .quad 0                 # 64-bit physical pointer to the
-                                               # ACPI RSDP table, added with
-                                               # version 2.14
-
 # End of setup header #####################################################
 
        .section ".entrytext", "ax"
index 106911b603bd95b355ddcf5d16028c4374c17035..374a19712e2009a0cbcb0c3048d4489cf5c2f9d9 100644 (file)
@@ -438,26 +438,6 @@ int x86_setup_perfctr(struct perf_event *event)
        if (config == -1LL)
                return -EINVAL;
 
-       /*
-        * Branch tracing:
-        */
-       if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
-           !attr->freq && hwc->sample_period == 1) {
-               /* BTS is not supported by this architecture. */
-               if (!x86_pmu.bts_active)
-                       return -EOPNOTSUPP;
-
-               /* BTS is currently only allowed for user-mode. */
-               if (!attr->exclude_kernel)
-                       return -EOPNOTSUPP;
-
-               /* disallow bts if conflicting events are present */
-               if (x86_add_exclusive(x86_lbr_exclusive_lbr))
-                       return -EBUSY;
-
-               event->destroy = hw_perf_lbr_event_destroy;
-       }
-
        hwc->config |= config;
 
        return 0;
index 273c62e8154632f524e04e16630bcdb6c958b8c0..ecc3e34ca955f720579aef805afe26f2b49a9e57 100644 (file)
@@ -2306,14 +2306,18 @@ static int handle_pmi_common(struct pt_regs *regs, u64 status)
        return handled;
 }
 
-static bool disable_counter_freezing;
+static bool disable_counter_freezing = true;
 static int __init intel_perf_counter_freezing_setup(char *s)
 {
-       disable_counter_freezing = true;
-       pr_info("Intel PMU Counter freezing feature disabled\n");
+       bool res;
+
+       if (kstrtobool(s, &res))
+               return -EINVAL;
+
+       disable_counter_freezing = !res;
        return 1;
 }
-__setup("disable_counter_freezing", intel_perf_counter_freezing_setup);
+__setup("perf_v4_pmi=", intel_perf_counter_freezing_setup);
 
 /*
  * Simplified handler for Arch Perfmon v4:
@@ -2470,16 +2474,7 @@ done:
 static struct event_constraint *
 intel_bts_constraints(struct perf_event *event)
 {
-       struct hw_perf_event *hwc = &event->hw;
-       unsigned int hw_event, bts_event;
-
-       if (event->attr.freq)
-               return NULL;
-
-       hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
-       bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
-
-       if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
+       if (unlikely(intel_pmu_has_bts(event)))
                return &bts_constraint;
 
        return NULL;
@@ -3098,10 +3093,51 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event)
        return flags;
 }
 
+static int intel_pmu_bts_config(struct perf_event *event)
+{
+       struct perf_event_attr *attr = &event->attr;
+
+       if (unlikely(intel_pmu_has_bts(event))) {
+               /* BTS is not supported by this architecture. */
+               if (!x86_pmu.bts_active)
+                       return -EOPNOTSUPP;
+
+               /* BTS is currently only allowed for user-mode. */
+               if (!attr->exclude_kernel)
+                       return -EOPNOTSUPP;
+
+               /* BTS is not allowed for precise events. */
+               if (attr->precise_ip)
+                       return -EOPNOTSUPP;
+
+               /* disallow bts if conflicting events are present */
+               if (x86_add_exclusive(x86_lbr_exclusive_lbr))
+                       return -EBUSY;
+
+               event->destroy = hw_perf_lbr_event_destroy;
+       }
+
+       return 0;
+}
+
+static int core_pmu_hw_config(struct perf_event *event)
+{
+       int ret = x86_pmu_hw_config(event);
+
+       if (ret)
+               return ret;
+
+       return intel_pmu_bts_config(event);
+}
+
 static int intel_pmu_hw_config(struct perf_event *event)
 {
        int ret = x86_pmu_hw_config(event);
 
+       if (ret)
+               return ret;
+
+       ret = intel_pmu_bts_config(event);
        if (ret)
                return ret;
 
@@ -3127,7 +3163,7 @@ static int intel_pmu_hw_config(struct perf_event *event)
                /*
                 * BTS is set up earlier in this path, so don't account twice
                 */
-               if (!intel_pmu_has_bts(event)) {
+               if (!unlikely(intel_pmu_has_bts(event))) {
                        /* disallow lbr if conflicting events are present */
                        if (x86_add_exclusive(x86_lbr_exclusive_lbr))
                                return -EBUSY;
@@ -3596,7 +3632,7 @@ static __initconst const struct x86_pmu core_pmu = {
        .enable_all             = core_pmu_enable_all,
        .enable                 = core_pmu_enable_event,
        .disable                = x86_pmu_disable_event,
-       .hw_config              = x86_pmu_hw_config,
+       .hw_config              = core_pmu_hw_config,
        .schedule_events        = x86_schedule_events,
        .eventsel               = MSR_ARCH_PERFMON_EVENTSEL0,
        .perfctr                = MSR_ARCH_PERFMON_PERFCTR0,
index adae087cecdda0b6b1aeb78bb51fdb55a61696ed..78d7b7031bfccb8ec2dbcd7de6e54a29fd1365ce 100644 (file)
@@ -859,11 +859,16 @@ static inline int amd_pmu_init(void)
 
 static inline bool intel_pmu_has_bts(struct perf_event *event)
 {
-       if (event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
-           !event->attr.freq && event->hw.sample_period == 1)
-               return true;
+       struct hw_perf_event *hwc = &event->hw;
+       unsigned int hw_event, bts_event;
+
+       if (event->attr.freq)
+               return false;
+
+       hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
+       bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
 
-       return false;
+       return hw_event == bts_event && hwc->sample_period == 1;
 }
 
 int intel_pmu_save_and_restart(struct perf_event *event);
index 5f7290e6e954e9428294d5bf732929918d7868f5..69dcdf195b6112b691616e2512f8a4ecca4796a1 100644 (file)
@@ -226,7 +226,7 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu)
                     "3: movl $-2,%[err]\n\t"                           \
                     "jmp 2b\n\t"                                       \
                     ".popsection\n\t"                                  \
-                    _ASM_EXTABLE_UA(1b, 3b)                            \
+                    _ASM_EXTABLE(1b, 3b)                               \
                     : [err] "=r" (err)                                 \
                     : "D" (st), "m" (*st), "a" (lmask), "d" (hmask)    \
                     : "memory")
index 55e51ff7e421f80b9145036b9356aa1a63ff21ce..fbda5a917c5b772dca40724bb2c24c189c38be91 100644 (file)
@@ -1094,7 +1094,8 @@ struct kvm_x86_ops {
        bool (*has_wbinvd_exit)(void);
 
        u64 (*read_l1_tsc_offset)(struct kvm_vcpu *vcpu);
-       void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
+       /* Returns actual tsc_offset set in active VMCS */
+       u64 (*write_l1_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
        void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
 
index 0f842104862c3b063cf806566736274d9df3faea..b85a7c54c6a13b51f27b26f13a2dd52f148547a7 100644 (file)
@@ -303,6 +303,4 @@ extern void x86_init_noop(void);
 extern void x86_init_uint_noop(unsigned int unused);
 extern bool x86_pnpbios_disabled(void);
 
-void x86_verify_bootdata_version(void);
-
 #endif
index 22f89d040dddce756a53fc94c2bb1fbcf3abcb4b..60733f137e9a292f2e4fe0f9c783f4a3f1d103f2 100644 (file)
@@ -16,9 +16,6 @@
 #define RAMDISK_PROMPT_FLAG            0x8000
 #define RAMDISK_LOAD_FLAG              0x4000
 
-/* version flags */
-#define VERSION_WRITTEN        0x8000
-
 /* loadflags */
 #define LOADED_HIGH    (1<<0)
 #define KASLR_FLAG     (1<<1)
@@ -89,7 +86,6 @@ struct setup_header {
        __u64   pref_address;
        __u32   init_size;
        __u32   handover_offset;
-       __u64   acpi_rsdp_addr;
 } __attribute__((packed));
 
 struct sys_desc_table {
@@ -159,7 +155,8 @@ struct boot_params {
        __u8  _pad2[4];                                 /* 0x054 */
        __u64  tboot_addr;                              /* 0x058 */
        struct ist_info ist_info;                       /* 0x060 */
-       __u8  _pad3[16];                                /* 0x070 */
+       __u64 acpi_rsdp_addr;                           /* 0x070 */
+       __u8  _pad3[8];                                 /* 0x078 */
        __u8  hd0_info[16];     /* obsolete! */         /* 0x080 */
        __u8  hd1_info[16];     /* obsolete! */         /* 0x090 */
        struct sys_desc_table sys_desc_table; /* obsolete! */   /* 0x0a0 */
index 92c76bf97ad828436405ce27398d48ce25132f65..06635fbca81c0359c170bc1ef2266e499f526983 100644 (file)
@@ -1776,5 +1776,5 @@ void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 
 u64 x86_default_get_root_pointer(void)
 {
-       return boot_params.hdr.acpi_rsdp_addr;
+       return boot_params.acpi_rsdp_addr;
 }
index dd33c357548f11c0ac21c367d0edc20b34671218..e12454e21b8a5decc64af5e9143d2b469d6ecfbb 100644 (file)
@@ -56,7 +56,7 @@
 /* Threshold LVT offset is at MSR0xC0000410[15:12] */
 #define SMCA_THR_LVT_OFF       0xF000
 
-static bool thresholding_en;
+static bool thresholding_irq_en;
 
 static const char * const th_names[] = {
        "load_store",
@@ -534,9 +534,8 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
 
 set_offset:
        offset = setup_APIC_mce_threshold(offset, new);
-
-       if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
-               mce_threshold_vector = amd_threshold_interrupt;
+       if (offset == new)
+               thresholding_irq_en = true;
 
 done:
        mce_threshold_block_init(&b, offset);
@@ -1357,9 +1356,6 @@ int mce_threshold_remove_device(unsigned int cpu)
 {
        unsigned int bank;
 
-       if (!thresholding_en)
-               return 0;
-
        for (bank = 0; bank < mca_cfg.banks; ++bank) {
                if (!(per_cpu(bank_map, cpu) & (1 << bank)))
                        continue;
@@ -1377,9 +1373,6 @@ int mce_threshold_create_device(unsigned int cpu)
        struct threshold_bank **bp;
        int err = 0;
 
-       if (!thresholding_en)
-               return 0;
-
        bp = per_cpu(threshold_banks, cpu);
        if (bp)
                return 0;
@@ -1408,9 +1401,6 @@ static __init int threshold_init_device(void)
 {
        unsigned lcpu = 0;
 
-       if (mce_threshold_vector == amd_threshold_interrupt)
-               thresholding_en = true;
-
        /* to hit CPUs online before the notifier is up */
        for_each_online_cpu(lcpu) {
                int err = mce_threshold_create_device(lcpu);
@@ -1419,6 +1409,9 @@ static __init int threshold_init_device(void)
                        return err;
        }
 
+       if (thresholding_irq_en)
+               mce_threshold_vector = amd_threshold_interrupt;
+
        return 0;
 }
 /*
index 61a949d84dfa52aff8572bfd88a3e6dc43556222..d99a8ee9e185e00be294bace7596bddd1dcc02d1 100644 (file)
@@ -344,10 +344,10 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
                        sanitize_restored_xstate(tsk, &env, xfeatures, fx_only);
                }
 
+               local_bh_disable();
                fpu->initialized = 1;
-               preempt_disable();
                fpu__restore(fpu);
-               preempt_enable();
+               local_bh_enable();
 
                return err;
        } else {
index 01ebcb6f263e39accb3f8e53ab7eb5372e0726f7..7ee8067cbf45c7a6d7739962bad43b8caadc6f08 100644 (file)
@@ -994,7 +994,6 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
 {
        unsigned long old;
        int faulted;
-       struct ftrace_graph_ent trace;
        unsigned long return_hooker = (unsigned long)
                                &return_to_handler;
 
@@ -1046,19 +1045,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
                return;
        }
 
-       trace.func = self_addr;
-       trace.depth = current->curr_ret_stack + 1;
-
-       /* Only trace if the calling function expects to */
-       if (!ftrace_graph_entry(&trace)) {
+       if (function_graph_enter(old, self_addr, frame_pointer, parent))
                *parent = old;
-               return;
-       }
-
-       if (ftrace_push_return_trace(old, self_addr, &trace.depth,
-                                    frame_pointer, parent) == -EBUSY) {
-               *parent = old;
-               return;
-       }
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
index 76fa3b8365985783332b99186b10cdc9a15dd169..ec6fefbfd3c0454b009a2a7a04a76edc44b8c5e8 100644 (file)
@@ -37,7 +37,6 @@ asmlinkage __visible void __init i386_start_kernel(void)
        cr4_init_shadow();
 
        sanitize_boot_params(&boot_params);
-       x86_verify_bootdata_version();
 
        x86_early_init_platform_quirks();
 
index 7663a8eb602bcf8332a04c91508dc84710504701..16b1cbd3a61e272c38a7fbbc983d852074ea9450 100644 (file)
@@ -457,8 +457,6 @@ void __init x86_64_start_reservations(char *real_mode_data)
        if (!boot_params.hdr.version)
                copy_bootdata(__va(real_mode_data));
 
-       x86_verify_bootdata_version();
-
        x86_early_init_platform_quirks();
 
        switch (boot_params.hdr.hardware_subarch) {
index b74e7bfed6ab40826b782f495324e2782963abb4..d494b9bfe618cbc974b0d154bb401fa9dc9b6080 100644 (file)
@@ -1280,23 +1280,6 @@ void __init setup_arch(char **cmdline_p)
        unwind_init();
 }
 
-/*
- * From boot protocol 2.14 onwards we expect the bootloader to set the
- * version to "0x8000 | <used version>". In case we find a version >= 2.14
- * without the 0x8000 we assume the boot loader supports 2.13 only and
- * reset the version accordingly. The 0x8000 flag is removed in any case.
- */
-void __init x86_verify_bootdata_version(void)
-{
-       if (boot_params.hdr.version & VERSION_WRITTEN)
-               boot_params.hdr.version &= ~VERSION_WRITTEN;
-       else if (boot_params.hdr.version >= 0x020e)
-               boot_params.hdr.version = 0x020d;
-
-       if (boot_params.hdr.version < 0x020e)
-               boot_params.hdr.acpi_rsdp_addr = 0;
-}
-
 #ifdef CONFIG_X86_32
 
 static struct resource video_ram_resource = {
index 89db20f8cb707666494c906bafedf958508ed12d..c4533d05c214b9e5d776217b5f9e6cec885d31ef 100644 (file)
@@ -55,7 +55,7 @@
 #define PRIo64 "o"
 
 /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
-#define apic_debug(fmt, arg...)
+#define apic_debug(fmt, arg...) do {} while (0)
 
 /* 14 is the version for Xeon and Pentium 8.4.8*/
 #define APIC_VERSION                   (0x14UL | ((KVM_APIC_LVT_NUM - 1) << 16))
@@ -576,6 +576,11 @@ int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
        rcu_read_lock();
        map = rcu_dereference(kvm->arch.apic_map);
 
+       if (unlikely(!map)) {
+               count = -EOPNOTSUPP;
+               goto out;
+       }
+
        if (min > map->max_apic_id)
                goto out;
        /* Bits above cluster_size are masked in the caller.  */
index cf5f572f230520b4f00694b0afe8ec6738e89868..7c03c0f35444ff9a112a2f3406a894477eaddc2c 100644 (file)
@@ -5074,9 +5074,9 @@ static bool need_remote_flush(u64 old, u64 new)
 }
 
 static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
-                                   const u8 *new, int *bytes)
+                                   int *bytes)
 {
-       u64 gentry;
+       u64 gentry = 0;
        int r;
 
        /*
@@ -5088,22 +5088,12 @@ static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa,
                /* Handle a 32-bit guest writing two halves of a 64-bit gpte */
                *gpa &= ~(gpa_t)7;
                *bytes = 8;
-               r = kvm_vcpu_read_guest(vcpu, *gpa, &gentry, 8);
-               if (r)
-                       gentry = 0;
-               new = (const u8 *)&gentry;
        }
 
-       switch (*bytes) {
-       case 4:
-               gentry = *(const u32 *)new;
-               break;
-       case 8:
-               gentry = *(const u64 *)new;
-               break;
-       default:
-               gentry = 0;
-               break;
+       if (*bytes == 4 || *bytes == 8) {
+               r = kvm_vcpu_read_guest_atomic(vcpu, *gpa, &gentry, *bytes);
+               if (r)
+                       gentry = 0;
        }
 
        return gentry;
@@ -5207,8 +5197,6 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 
        pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);
 
-       gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes);
-
        /*
         * No need to care whether allocation memory is successful
         * or not since pte prefetch is skiped if it does not have
@@ -5217,6 +5205,9 @@ static void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
        mmu_topup_memory_caches(vcpu);
 
        spin_lock(&vcpu->kvm->mmu_lock);
+
+       gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, &bytes);
+
        ++vcpu->kvm->stat.mmu_pte_write;
        kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);
 
index 0e21ccc46792f6bcc6665ff63979f23979aa1829..cc6467b35a85f6cec9300011cfa0c464574ed5d3 100644 (file)
@@ -1446,7 +1446,7 @@ static u64 svm_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
        return vcpu->arch.tsc_offset;
 }
 
-static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
+static u64 svm_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        u64 g_tsc_offset = 0;
@@ -1464,6 +1464,7 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
        svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
 
        mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
+       return svm->vmcb->control.tsc_offset;
 }
 
 static void avic_init_vmcb(struct vcpu_svm *svm)
@@ -1664,20 +1665,23 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
 static int avic_init_access_page(struct kvm_vcpu *vcpu)
 {
        struct kvm *kvm = vcpu->kvm;
-       int ret;
+       int ret = 0;
 
+       mutex_lock(&kvm->slots_lock);
        if (kvm->arch.apic_access_page_done)
-               return 0;
+               goto out;
 
-       ret = x86_set_memory_region(kvm,
-                                   APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
-                                   APIC_DEFAULT_PHYS_BASE,
-                                   PAGE_SIZE);
+       ret = __x86_set_memory_region(kvm,
+                                     APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
+                                     APIC_DEFAULT_PHYS_BASE,
+                                     PAGE_SIZE);
        if (ret)
-               return ret;
+               goto out;
 
        kvm->arch.apic_access_page_done = true;
-       return 0;
+out:
+       mutex_unlock(&kvm->slots_lock);
+       return ret;
 }
 
 static int avic_init_backing_page(struct kvm_vcpu *vcpu)
@@ -2189,21 +2193,31 @@ out:
        return ERR_PTR(err);
 }
 
+static void svm_clear_current_vmcb(struct vmcb *vmcb)
+{
+       int i;
+
+       for_each_online_cpu(i)
+               cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL);
+}
+
 static void svm_free_vcpu(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
+       /*
+        * The vmcb page can be recycled, causing a false negative in
+        * svm_vcpu_load(). So, ensure that no logical CPU has this
+        * vmcb page recorded as its current vmcb.
+        */
+       svm_clear_current_vmcb(svm->vmcb);
+
        __free_page(pfn_to_page(__sme_clr(svm->vmcb_pa) >> PAGE_SHIFT));
        __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
        __free_page(virt_to_page(svm->nested.hsave));
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, svm);
-       /*
-        * The vmcb page can be recycled, causing a false negative in
-        * svm_vcpu_load(). So do a full IBPB now.
-        */
-       indirect_branch_prediction_barrier();
 }
 
 static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
@@ -7149,7 +7163,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .has_wbinvd_exit = svm_has_wbinvd_exit,
 
        .read_l1_tsc_offset = svm_read_l1_tsc_offset,
-       .write_tsc_offset = svm_write_tsc_offset,
+       .write_l1_tsc_offset = svm_write_l1_tsc_offset,
 
        .set_tdp_cr3 = set_tdp_cr3,
 
index 4555077d69ce204148facb207f46ddf882483231..02edd9960e9d94cf8cbac80ea1bfccc5673f3089 100644 (file)
@@ -174,6 +174,7 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
  * refer SDM volume 3b section 21.6.13 & 22.1.3.
  */
 static unsigned int ple_gap = KVM_DEFAULT_PLE_GAP;
+module_param(ple_gap, uint, 0444);
 
 static unsigned int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW;
 module_param(ple_window, uint, 0444);
@@ -984,6 +985,7 @@ struct vcpu_vmx {
        struct shared_msr_entry *guest_msrs;
        int                   nmsrs;
        int                   save_nmsrs;
+       bool                  guest_msrs_dirty;
        unsigned long         host_idt_base;
 #ifdef CONFIG_X86_64
        u64                   msr_host_kernel_gs_base;
@@ -1306,7 +1308,7 @@ static void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
 static bool nested_vmx_is_page_fault_vmexit(struct vmcs12 *vmcs12,
                                            u16 error_code);
 static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
-static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
                                                          u32 msr, int type);
 
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
@@ -1610,12 +1612,6 @@ static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 
-       /* We don't support disabling the feature for simplicity. */
-       if (vmx->nested.enlightened_vmcs_enabled)
-               return 0;
-
-       vmx->nested.enlightened_vmcs_enabled = true;
-
        /*
         * vmcs_version represents the range of supported Enlightened VMCS
         * versions: lower 8 bits is the minimal version, higher 8 bits is the
@@ -1625,6 +1621,12 @@ static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
        if (vmcs_version)
                *vmcs_version = (KVM_EVMCS_VERSION << 8) | 1;
 
+       /* We don't support disabling the feature for simplicity. */
+       if (vmx->nested.enlightened_vmcs_enabled)
+               return 0;
+
+       vmx->nested.enlightened_vmcs_enabled = true;
+
        vmx->nested.msrs.pinbased_ctls_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
        vmx->nested.msrs.entry_ctls_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
        vmx->nested.msrs.exit_ctls_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
@@ -2897,6 +2899,20 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
 
        vmx->req_immediate_exit = false;
 
+       /*
+        * Note that guest MSRs to be saved/restored can also be changed
+        * when guest state is loaded. This happens when guest transitions
+        * to/from long-mode by setting MSR_EFER.LMA.
+        */
+       if (!vmx->loaded_cpu_state || vmx->guest_msrs_dirty) {
+               vmx->guest_msrs_dirty = false;
+               for (i = 0; i < vmx->save_nmsrs; ++i)
+                       kvm_set_shared_msr(vmx->guest_msrs[i].index,
+                                          vmx->guest_msrs[i].data,
+                                          vmx->guest_msrs[i].mask);
+
+       }
+
        if (vmx->loaded_cpu_state)
                return;
 
@@ -2957,11 +2973,6 @@ static void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
                vmcs_writel(HOST_GS_BASE, gs_base);
                host_state->gs_base = gs_base;
        }
-
-       for (i = 0; i < vmx->save_nmsrs; ++i)
-               kvm_set_shared_msr(vmx->guest_msrs[i].index,
-                                  vmx->guest_msrs[i].data,
-                                  vmx->guest_msrs[i].mask);
 }
 
 static void vmx_prepare_switch_to_host(struct vcpu_vmx *vmx)
@@ -3436,6 +3447,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
                move_msr_up(vmx, index, save_nmsrs++);
 
        vmx->save_nmsrs = save_nmsrs;
+       vmx->guest_msrs_dirty = true;
 
        if (cpu_has_vmx_msr_bitmap())
                vmx_update_msr_bitmap(&vmx->vcpu);
@@ -3452,11 +3464,9 @@ static u64 vmx_read_l1_tsc_offset(struct kvm_vcpu *vcpu)
        return vcpu->arch.tsc_offset;
 }
 
-/*
- * writes 'offset' into guest's timestamp counter offset register
- */
-static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
+static u64 vmx_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
+       u64 active_offset = offset;
        if (is_guest_mode(vcpu)) {
                /*
                 * We're here if L1 chose not to trap WRMSR to TSC. According
@@ -3464,17 +3474,16 @@ static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
                 * set for L2 remains unchanged, and still needs to be added
                 * to the newly set TSC to get L2's TSC.
                 */
-               struct vmcs12 *vmcs12;
-               /* recalculate vmcs02.TSC_OFFSET: */
-               vmcs12 = get_vmcs12(vcpu);
-               vmcs_write64(TSC_OFFSET, offset +
-                       (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING) ?
-                        vmcs12->tsc_offset : 0));
+               struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+               if (nested_cpu_has(vmcs12, CPU_BASED_USE_TSC_OFFSETING))
+                       active_offset += vmcs12->tsc_offset;
        } else {
                trace_kvm_write_tsc_offset(vcpu->vcpu_id,
                                           vmcs_read64(TSC_OFFSET), offset);
-               vmcs_write64(TSC_OFFSET, offset);
        }
+
+       vmcs_write64(TSC_OFFSET, active_offset);
+       return active_offset;
 }
 
 /*
@@ -5944,7 +5953,7 @@ static void free_vpid(int vpid)
        spin_unlock(&vmx_vpid_lock);
 }
 
-static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
                                                          u32 msr, int type)
 {
        int f = sizeof(unsigned long);
@@ -5982,7 +5991,7 @@ static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bit
        }
 }
 
-static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
                                                         u32 msr, int type)
 {
        int f = sizeof(unsigned long);
@@ -6020,7 +6029,7 @@ static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitm
        }
 }
 
-static void __always_inline vmx_set_intercept_for_msr(unsigned long *msr_bitmap,
+static __always_inline void vmx_set_intercept_for_msr(unsigned long *msr_bitmap,
                                                      u32 msr, int type, bool value)
 {
        if (value)
@@ -8664,8 +8673,6 @@ static int copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx)
        struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
        struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
 
-       vmcs12->hdr.revision_id = evmcs->revision_id;
-
        /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
        vmcs12->tpr_threshold = evmcs->tpr_threshold;
        vmcs12->guest_rip = evmcs->guest_rip;
@@ -9369,7 +9376,30 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
 
                vmx->nested.hv_evmcs = kmap(vmx->nested.hv_evmcs_page);
 
-               if (vmx->nested.hv_evmcs->revision_id != VMCS12_REVISION) {
+               /*
+                * Currently, KVM only supports eVMCS version 1
+                * (== KVM_EVMCS_VERSION) and thus we expect guest to set this
+                * value to first u32 field of eVMCS which should specify eVMCS
+                * VersionNumber.
+                *
+                * Guest should be aware of supported eVMCS versions by host by
+                * examining CPUID.0x4000000A.EAX[0:15]. Host userspace VMM is
+                * expected to set this CPUID leaf according to the value
+                * returned in vmcs_version from nested_enable_evmcs().
+                *
+                * However, it turns out that Microsoft Hyper-V fails to comply
+                * to their own invented interface: When Hyper-V use eVMCS, it
+                * just sets first u32 field of eVMCS to revision_id specified
+                * in MSR_IA32_VMX_BASIC. Instead of used eVMCS version number
+                * which is one of the supported versions specified in
+                * CPUID.0x4000000A.EAX[0:15].
+                *
+                * To overcome Hyper-V bug, we accept here either a supported
+                * eVMCS version or VMCS12 revision_id as valid values for first
+                * u32 field of eVMCS.
+                */
+               if ((vmx->nested.hv_evmcs->revision_id != KVM_EVMCS_VERSION) &&
+                   (vmx->nested.hv_evmcs->revision_id != VMCS12_REVISION)) {
                        nested_release_evmcs(vcpu);
                        return 0;
                }
@@ -9390,9 +9420,11 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu,
                 * present in struct hv_enlightened_vmcs, ...). Make sure there
                 * are no leftovers.
                 */
-               if (from_launch)
-                       memset(vmx->nested.cached_vmcs12, 0,
-                              sizeof(*vmx->nested.cached_vmcs12));
+               if (from_launch) {
+                       struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
+                       memset(vmcs12, 0, sizeof(*vmcs12));
+                       vmcs12->hdr.revision_id = VMCS12_REVISION;
+               }
 
        }
        return 1;
@@ -15062,7 +15094,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
        .read_l1_tsc_offset = vmx_read_l1_tsc_offset,
-       .write_tsc_offset = vmx_write_tsc_offset,
+       .write_l1_tsc_offset = vmx_write_l1_tsc_offset,
 
        .set_tdp_cr3 = vmx_set_cr3,
 
index 5cd5647120f2b439a8d63b52d223499b48e5ff9e..d02937760c3ba8adc6de37ed4b39db9a926f320d 100644 (file)
@@ -1665,8 +1665,7 @@ EXPORT_SYMBOL_GPL(kvm_read_l1_tsc);
 
 static void kvm_vcpu_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
-       kvm_x86_ops->write_tsc_offset(vcpu, offset);
-       vcpu->arch.tsc_offset = offset;
+       vcpu->arch.tsc_offset = kvm_x86_ops->write_l1_tsc_offset(vcpu, offset);
 }
 
 static inline bool kvm_check_tsc_unstable(void)
@@ -1794,7 +1793,8 @@ EXPORT_SYMBOL_GPL(kvm_write_tsc);
 static inline void adjust_tsc_offset_guest(struct kvm_vcpu *vcpu,
                                           s64 adjustment)
 {
-       kvm_vcpu_write_tsc_offset(vcpu, vcpu->arch.tsc_offset + adjustment);
+       u64 tsc_offset = kvm_x86_ops->read_l1_tsc_offset(vcpu);
+       kvm_vcpu_write_tsc_offset(vcpu, tsc_offset + adjustment);
 }
 
 static inline void adjust_tsc_offset_host(struct kvm_vcpu *vcpu, s64 adjustment)
@@ -6918,6 +6918,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
        clock_pairing.nsec = ts.tv_nsec;
        clock_pairing.tsc = kvm_read_l1_tsc(vcpu, cycle);
        clock_pairing.flags = 0;
+       memset(&clock_pairing.pad, 0, sizeof(clock_pairing.pad));
 
        ret = 0;
        if (kvm_write_guest(vcpu->kvm, paddr, &clock_pairing,
@@ -7455,7 +7456,8 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
        else {
                if (vcpu->arch.apicv_active)
                        kvm_x86_ops->sync_pir_to_irr(vcpu);
-               kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
+               if (ioapic_in_kernel(vcpu->kvm))
+                       kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
        }
 
        if (is_guest_mode(vcpu))
index 67904f55f1884f52893b3a99b1be785a48dc69da..120dd746a14751f3de4317a35921b2037d8c7cdd 100644 (file)
@@ -94,14 +94,14 @@ int main(void)
        DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
        DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable));
 #if XTENSA_HAVE_COPROCESSORS
-       DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp));
-       DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp));
+       DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0));
+       DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1));
+       DEFINE(THREAD_XTREGS_CP2, offsetof(struct thread_info, xtregs_cp.cp2));
+       DEFINE(THREAD_XTREGS_CP3, offsetof(struct thread_info, xtregs_cp.cp3));
+       DEFINE(THREAD_XTREGS_CP4, offsetof(struct thread_info, xtregs_cp.cp4));
+       DEFINE(THREAD_XTREGS_CP5, offsetof(struct thread_info, xtregs_cp.cp5));
+       DEFINE(THREAD_XTREGS_CP6, offsetof(struct thread_info, xtregs_cp.cp6));
+       DEFINE(THREAD_XTREGS_CP7, offsetof(struct thread_info, xtregs_cp.cp7));
 #endif
        DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user));
        DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t));
index 483dcfb6e681d7d483ef8ebfb948d91b7ee8f1fd..4bb68133a72af93ad00e82d08abb7d26a783b86d 100644 (file)
@@ -94,18 +94,21 @@ void coprocessor_release_all(struct thread_info *ti)
 
 void coprocessor_flush_all(struct thread_info *ti)
 {
-       unsigned long cpenable;
+       unsigned long cpenable, old_cpenable;
        int i;
 
        preempt_disable();
 
+       RSR_CPENABLE(old_cpenable);
        cpenable = ti->cpenable;
+       WSR_CPENABLE(cpenable);
 
        for (i = 0; i < XCHAL_CP_MAX; i++) {
                if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti)
                        coprocessor_flush(ti, i);
                cpenable >>= 1;
        }
+       WSR_CPENABLE(old_cpenable);
 
        preempt_enable();
 }
index c0845cb1cbb9944ed7deaee9bffa3685171574c3..d9541be0605ad52793e5d59a11b2a8dda7f975a7 100644 (file)
@@ -127,12 +127,37 @@ static int ptrace_setregs(struct task_struct *child, void __user *uregs)
 }
 
 
+#if XTENSA_HAVE_COPROCESSORS
+#define CP_OFFSETS(cp) \
+       { \
+               .elf_xtregs_offset = offsetof(elf_xtregs_t, cp), \
+               .ti_offset = offsetof(struct thread_info, xtregs_cp.cp), \
+               .sz = sizeof(xtregs_ ## cp ## _t), \
+       }
+
+static const struct {
+       size_t elf_xtregs_offset;
+       size_t ti_offset;
+       size_t sz;
+} cp_offsets[] = {
+       CP_OFFSETS(cp0),
+       CP_OFFSETS(cp1),
+       CP_OFFSETS(cp2),
+       CP_OFFSETS(cp3),
+       CP_OFFSETS(cp4),
+       CP_OFFSETS(cp5),
+       CP_OFFSETS(cp6),
+       CP_OFFSETS(cp7),
+};
+#endif
+
 static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
 {
        struct pt_regs *regs = task_pt_regs(child);
        struct thread_info *ti = task_thread_info(child);
        elf_xtregs_t __user *xtregs = uregs;
        int ret = 0;
+       int i __maybe_unused;
 
        if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t)))
                return -EIO;
@@ -140,8 +165,13 @@ static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
 #if XTENSA_HAVE_COPROCESSORS
        /* Flush all coprocessor registers to memory. */
        coprocessor_flush_all(ti);
-       ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp,
-                             sizeof(xtregs_coprocessor_t));
+
+       for (i = 0; i < ARRAY_SIZE(cp_offsets); ++i)
+               ret |= __copy_to_user((char __user *)xtregs +
+                                     cp_offsets[i].elf_xtregs_offset,
+                                     (const char *)ti +
+                                     cp_offsets[i].ti_offset,
+                                     cp_offsets[i].sz);
 #endif
        ret |= __copy_to_user(&xtregs->opt, &regs->xtregs_opt,
                              sizeof(xtregs->opt));
@@ -157,6 +187,7 @@ static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
        struct pt_regs *regs = task_pt_regs(child);
        elf_xtregs_t *xtregs = uregs;
        int ret = 0;
+       int i __maybe_unused;
 
        if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t)))
                return -EFAULT;
@@ -166,8 +197,11 @@ static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
        coprocessor_flush_all(ti);
        coprocessor_release_all(ti);
 
-       ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0,
-                               sizeof(xtregs_coprocessor_t));
+       for (i = 0; i < ARRAY_SIZE(cp_offsets); ++i)
+               ret |= __copy_from_user((char *)ti + cp_offsets[i].ti_offset,
+                                       (const char __user *)xtregs +
+                                       cp_offsets[i].elf_xtregs_offset,
+                                       cp_offsets[i].sz);
 #endif
        ret |= __copy_from_user(&regs->xtregs_opt, &xtregs->opt,
                                sizeof(xtregs->opt));
index 0d42f30e5b25d93b33f4566a72658f0ccabf7254..9920fac6413ffb94cce8d5eb146dbb15df5283a4 100644 (file)
@@ -244,7 +244,6 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
 {
        acpi_status status;
        u32 buffer_length;
-       u32 data_length;
        void *buffer;
        union acpi_operand_object *buffer_desc;
        u32 function;
@@ -282,14 +281,12 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
        case ACPI_ADR_SPACE_SMBUS:
 
                buffer_length = ACPI_SMBUS_BUFFER_SIZE;
-               data_length = ACPI_SMBUS_DATA_SIZE;
                function = ACPI_WRITE | (obj_desc->field.attribute << 16);
                break;
 
        case ACPI_ADR_SPACE_IPMI:
 
                buffer_length = ACPI_IPMI_BUFFER_SIZE;
-               data_length = ACPI_IPMI_DATA_SIZE;
                function = ACPI_WRITE;
                break;
 
@@ -310,7 +307,6 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
                /* Add header length to get the full size of the buffer */
 
                buffer_length += ACPI_SERIAL_HEADER_SIZE;
-               data_length = source_desc->buffer.pointer[1];
                function = ACPI_WRITE | (accessor_type << 16);
                break;
 
@@ -318,20 +314,6 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
                return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
        }
 
-#if 0
-       OBSOLETE ?
-           /* Check for possible buffer overflow */
-           if (data_length > source_desc->buffer.length) {
-               ACPI_ERROR((AE_INFO,
-                           "Length in buffer header (%u)(%u) is greater than "
-                           "the physical buffer length (%u) and will overflow",
-                           data_length, buffer_length,
-                           source_desc->buffer.length));
-
-               return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
-       }
-#endif
-
        /* Create the transfer/bidirectional/return buffer */
 
        buffer_desc = acpi_ut_create_buffer_object(buffer_length);
@@ -342,7 +324,8 @@ acpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
        /* Copy the input buffer data to the transfer buffer */
 
        buffer = buffer_desc->buffer.pointer;
-       memcpy(buffer, source_desc->buffer.pointer, data_length);
+       memcpy(buffer, source_desc->buffer.pointer,
+              min(buffer_length, source_desc->buffer.length));
 
        /* Lock entire transaction if requested */
 
index 4e46dc9e41ad01142ffdcfe1c38921df9db0ebda..11e1663bdc4dee0e2cfd7cd9ba61783d00277bbf 100644 (file)
@@ -1410,7 +1410,7 @@ static int init_q(struct fs_dev *dev, struct queue *txq, int queue,
 
        func_enter ();
 
-       fs_dprintk (FS_DEBUG_INIT, "Inititing queue at %x: %d entries:\n", 
+       fs_dprintk (FS_DEBUG_INIT, "Initializing queue at %x: %d entries:\n",
                    queue, nentries);
 
        p = aligned_kmalloc (sz, GFP_KERNEL, 0x10);
@@ -1443,7 +1443,7 @@ static int init_fp(struct fs_dev *dev, struct freepool *fp, int queue,
 {
        func_enter ();
 
-       fs_dprintk (FS_DEBUG_INIT, "Inititing free pool at %x:\n", queue);
+       fs_dprintk (FS_DEBUG_INIT, "Initializing free pool at %x:\n", queue);
 
        write_fs (dev, FP_CNF(queue), (bufsize * RBFP_RBS) | RBFP_RBSVAL | RBFP_CME);
        write_fs (dev, FP_SA(queue),  0);
index fad7c62cfc0e422f3b8459653a561f4dee770a6e..415849bab2339a4168d9fff236b8302a02adc284 100644 (file)
@@ -969,13 +969,33 @@ bool efi_is_table_address(unsigned long phys_addr)
 static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
 static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
 
-int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
+static int __init efi_memreserve_map_root(void)
+{
+       if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
+               return -ENODEV;
+
+       efi_memreserve_root = memremap(efi.mem_reserve,
+                                      sizeof(*efi_memreserve_root),
+                                      MEMREMAP_WB);
+       if (WARN_ON_ONCE(!efi_memreserve_root))
+               return -ENOMEM;
+       return 0;
+}
+
+int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 {
        struct linux_efi_memreserve *rsv;
+       int rc;
 
-       if (!efi_memreserve_root)
+       if (efi_memreserve_root == (void *)ULONG_MAX)
                return -ENODEV;
 
+       if (!efi_memreserve_root) {
+               rc = efi_memreserve_map_root();
+               if (rc)
+                       return rc;
+       }
+
        rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
        if (!rsv)
                return -ENOMEM;
@@ -993,14 +1013,10 @@ int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
 
 static int __init efi_memreserve_root_init(void)
 {
-       if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
-               return -ENODEV;
-
-       efi_memreserve_root = memremap(efi.mem_reserve,
-                                      sizeof(*efi_memreserve_root),
-                                      MEMREMAP_WB);
-       if (!efi_memreserve_root)
-               return -ENOMEM;
+       if (efi_memreserve_root)
+               return 0;
+       if (efi_memreserve_map_root())
+               efi_memreserve_root = (void *)ULONG_MAX;
        return 0;
 }
 early_initcall(efi_memreserve_root_init);
index dad0e2342df9db7641f77f1473a87f6d78d99050..0877ff9a959445ad77a263f2ba1105ec5e795822 100644 (file)
@@ -181,7 +181,7 @@ static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
 
        if (level == adev->vm_manager.root_level)
                /* For the root directory */
-               return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift;
+               return round_up(adev->vm_manager.max_pfn, 1ULL << shift) >> shift;
        else if (level != AMDGPU_VM_PTB)
                /* Everything in between */
                return 512;
@@ -1656,9 +1656,11 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
                        if (!amdgpu_vm_pt_descendant(adev, &cursor))
                                return -ENOENT;
                        continue;
-               } else if (frag >= parent_shift) {
+               } else if (frag >= parent_shift &&
+                          cursor.level - 1 != adev->vm_manager.root_level) {
                        /* If the fragment size is even larger than the parent
-                        * shift we should go up one level and check it again.
+                        * shift we should go up one level and check it again
+                        * unless one level up is the root level.
                         */
                        if (!amdgpu_vm_pt_ancestor(&cursor))
                                return -ENOENT;
@@ -1666,10 +1668,10 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
                }
 
                /* Looks good so far, calculate parameters for the update */
-               incr = AMDGPU_GPU_PAGE_SIZE << shift;
+               incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;
                mask = amdgpu_vm_entries_mask(adev, cursor.level);
                pe_start = ((cursor.pfn >> shift) & mask) * 8;
-               entry_end = (mask + 1) << shift;
+               entry_end = (uint64_t)(mask + 1) << shift;
                entry_end += cursor.pfn & ~(entry_end - 1);
                entry_end = min(entry_end, end);
 
@@ -1682,7 +1684,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
                                              flags | AMDGPU_PTE_FRAG(frag));
 
                        pe_start += nptes * 8;
-                       dst += nptes * AMDGPU_GPU_PAGE_SIZE << shift;
+                       dst += (uint64_t)nptes * AMDGPU_GPU_PAGE_SIZE << shift;
 
                        frag_start = upd_end;
                        if (frag_start >= frag_end) {
index 6d7baf59d6e11e947c83ef34d716c5a546d6460f..21363b2b2ee5729e7807b9046aa2872438044ae1 100644 (file)
@@ -2440,12 +2440,13 @@ static void gfx_v9_0_rlc_start(struct amdgpu_device *adev)
 #endif
 
        WREG32_FIELD15(GC, 0, RLC_CNTL, RLC_ENABLE_F32, 1);
+       udelay(50);
 
        /* carrizo do enable cp interrupt after cp inited */
-       if (!(adev->flags & AMD_IS_APU))
+       if (!(adev->flags & AMD_IS_APU)) {
                gfx_v9_0_enable_gui_idle_interrupt(adev, true);
-
-       udelay(50);
+               udelay(50);
+       }
 
 #ifdef AMDGPU_RLC_DEBUG_RETRY
        /* RLC_GPM_GENERAL_6 : RLC Ucode version */
index d02c32a1039c02b97f02d721030ae82e546799df..1b0d209d836764ee16c4b9159100a52a6753f7b2 100644 (file)
@@ -342,10 +342,9 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                master->connector_id);
 
        aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master);
+       drm_connector_attach_encoder(&aconnector->base,
+                                    &aconnector->mst_encoder->base);
 
-       /*
-        * TODO: understand why this one is needed
-        */
        drm_object_attach_property(
                &connector->base,
                dev->mode_config.path_property,
index dac355812adcbdcea7d68a40ff44bca90b0e0dcf..373700c05a00f9f3890d48fee79317edf77cedd8 100644 (file)
@@ -583,7 +583,8 @@ void ast_driver_unload(struct drm_device *dev)
        drm_mode_config_cleanup(dev);
 
        ast_mm_fini(ast);
-       pci_iounmap(dev->pdev, ast->ioregs);
+       if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET)
+               pci_iounmap(dev->pdev, ast->ioregs);
        pci_iounmap(dev->pdev, ast->regs);
        kfree(ast);
 }
index 7c6ac3cadb6b7fabcfe9a309d5fc201db6b75bf7..8bb355d5d43d80169fbfeb73954008b772616e15 100644 (file)
@@ -973,9 +973,21 @@ static int get_clock(void *i2c_priv)
 {
        struct ast_i2c_chan *i2c = i2c_priv;
        struct ast_private *ast = i2c->dev->dev_private;
-       uint32_t val;
+       uint32_t val, val2, count, pass;
+
+       count = 0;
+       pass = 0;
+       val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+       do {
+               val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+               if (val == val2) {
+                       pass++;
+               } else {
+                       pass = 0;
+                       val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
+               }
+       } while ((pass < 5) && (count++ < 0x10000));
 
-       val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4;
        return val & 1 ? 1 : 0;
 }
 
@@ -983,9 +995,21 @@ static int get_data(void *i2c_priv)
 {
        struct ast_i2c_chan *i2c = i2c_priv;
        struct ast_private *ast = i2c->dev->dev_private;
-       uint32_t val;
+       uint32_t val, val2, count, pass;
+
+       count = 0;
+       pass = 0;
+       val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+       do {
+               val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+               if (val == val2) {
+                       pass++;
+               } else {
+                       pass = 0;
+                       val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
+               }
+       } while ((pass < 5) && (count++ < 0x10000));
 
-       val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5;
        return val & 1 ? 1 : 0;
 }
 
@@ -998,7 +1022,7 @@ static void set_clock(void *i2c_priv, int clock)
 
        for (i = 0; i < 0x10000; i++) {
                ujcrb7 = ((clock & 0x01) ? 0 : 1);
-               ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7);
+               ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
                jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
                if (ujcrb7 == jtemp)
                        break;
@@ -1014,7 +1038,7 @@ static void set_data(void *i2c_priv, int data)
 
        for (i = 0; i < 0x10000; i++) {
                ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
-               ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7);
+               ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
                jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
                if (ujcrb7 == jtemp)
                        break;
index d9c0f75739054d88f9533a47684ec4c6f9fb30bf..1669c42c40ed3537cb9240de83a1128e38b816c5 100644 (file)
@@ -142,6 +142,7 @@ static int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
 
        lockdep_assert_held_once(&dev->master_mutex);
 
+       WARN_ON(fpriv->is_master);
        old_master = fpriv->master;
        fpriv->master = drm_master_create(dev);
        if (!fpriv->master) {
@@ -170,6 +171,7 @@ out_err:
        /* drop references and restore old master on failure */
        drm_master_put(&fpriv->master);
        fpriv->master = old_master;
+       fpriv->is_master = 0;
 
        return ret;
 }
index fe754022e356b033c2fa62af06c28f3612197df5..359d37d5c958c6b258053ba62804762f75d00087 100644 (file)
@@ -61,10 +61,12 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
        }
 
        mutex_lock(&dev_priv->drm.struct_mutex);
+       mmio_hw_access_pre(dev_priv);
        ret = i915_gem_gtt_insert(&dev_priv->ggtt.vm, node,
                                  size, I915_GTT_PAGE_SIZE,
                                  I915_COLOR_UNEVICTABLE,
                                  start, end, flags);
+       mmio_hw_access_post(dev_priv);
        mutex_unlock(&dev_priv->drm.struct_mutex);
        if (ret)
                gvt_err("fail to alloc %s gm space from host\n",
index 58e166effa456426d7fe2ee4f059a0533b4bfe0c..c7103dd2d8d571fde462f173dcc67efc0973cc69 100644 (file)
@@ -2447,10 +2447,11 @@ static void intel_vgpu_destroy_all_ppgtt_mm(struct intel_vgpu *vgpu)
 
 static void intel_vgpu_destroy_ggtt_mm(struct intel_vgpu *vgpu)
 {
-       struct intel_gvt_partial_pte *pos;
+       struct intel_gvt_partial_pte *pos, *next;
 
-       list_for_each_entry(pos,
-                       &vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list, list) {
+       list_for_each_entry_safe(pos, next,
+                                &vgpu->gtt.ggtt_mm->ggtt_mm.partial_pte_list,
+                                list) {
                gvt_dbg_mm("partial PTE update on hold 0x%lx : 0x%llx\n",
                        pos->offset, pos->data);
                kfree(pos);
index 36a5147cd01e5224b2c6563c29128d05688e7fba..d6e02c15ef97d995fd4ec2ab203c15e5ff8ab245 100644 (file)
@@ -158,6 +158,8 @@ static void load_render_mocs(struct drm_i915_private *dev_priv)
        int ring_id, i;
 
        for (ring_id = 0; ring_id < ARRAY_SIZE(regs); ring_id++) {
+               if (!HAS_ENGINE(dev_priv, ring_id))
+                       continue;
                offset.reg = regs[ring_id];
                for (i = 0; i < GEN9_MOCS_SIZE; i++) {
                        gen9_render_mocs.control_table[ring_id][i] =
index 05520202c96778c1401dac07a9b9ff768ba97b91..191b314f9e9e5ce92284beec9f4d27f54bdcc811 100644 (file)
@@ -45,6 +45,7 @@ struct meson_crtc {
        struct drm_crtc base;
        struct drm_pending_vblank_event *event;
        struct meson_drm *priv;
+       bool enabled;
 };
 #define to_meson_crtc(x) container_of(x, struct meson_crtc, base)
 
@@ -80,8 +81,7 @@ static const struct drm_crtc_funcs meson_crtc_funcs = {
 
 };
 
-static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
-                                    struct drm_crtc_state *old_state)
+static void meson_crtc_enable(struct drm_crtc *crtc)
 {
        struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
        struct drm_crtc_state *crtc_state = crtc->state;
@@ -101,6 +101,22 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
        writel_bits_relaxed(VPP_POSTBLEND_ENABLE, VPP_POSTBLEND_ENABLE,
                            priv->io_base + _REG(VPP_MISC));
 
+       drm_crtc_vblank_on(crtc);
+
+       meson_crtc->enabled = true;
+}
+
+static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
+                                    struct drm_crtc_state *old_state)
+{
+       struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
+       struct meson_drm *priv = meson_crtc->priv;
+
+       DRM_DEBUG_DRIVER("\n");
+
+       if (!meson_crtc->enabled)
+               meson_crtc_enable(crtc);
+
        priv->viu.osd1_enabled = true;
 }
 
@@ -110,6 +126,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
        struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
        struct meson_drm *priv = meson_crtc->priv;
 
+       drm_crtc_vblank_off(crtc);
+
        priv->viu.osd1_enabled = false;
        priv->viu.osd1_commit = false;
 
@@ -124,6 +142,8 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
 
                crtc->state->event = NULL;
        }
+
+       meson_crtc->enabled = false;
 }
 
 static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
@@ -132,6 +152,9 @@ static void meson_crtc_atomic_begin(struct drm_crtc *crtc,
        struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
        unsigned long flags;
 
+       if (crtc->state->enable && !meson_crtc->enabled)
+               meson_crtc_enable(crtc);
+
        if (crtc->state->event) {
                WARN_ON(drm_crtc_vblank_get(crtc) != 0);
 
index df7247cd93f98f9f237721bb1eddd104cbbdc345..2cb2ad26d71670c387b144dc34668567f1fa9c34 100644 (file)
@@ -706,6 +706,7 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
        .reg_read = meson_dw_hdmi_reg_read,
        .reg_write = meson_dw_hdmi_reg_write,
        .max_register = 0x10000,
+       .fast_io = true,
 };
 
 static bool meson_hdmi_connector_is_available(struct device *dev)
index acbbad3e322ca56957ff3b34228b694d12de30b3..be76f3d64bf2e7e1c85142a7d159228bf5905e6a 100644 (file)
@@ -71,6 +71,7 @@
  */
 
 /* HHI Registers */
+#define HHI_GCLK_MPEG2         0x148 /* 0x52 offset in data sheet */
 #define HHI_VDAC_CNTL0         0x2F4 /* 0xbd offset in data sheet */
 #define HHI_VDAC_CNTL1         0x2F8 /* 0xbe offset in data sheet */
 #define HHI_HDMI_PHY_CNTL0     0x3a0 /* 0xe8 offset in data sheet */
@@ -714,6 +715,7 @@ struct meson_hdmi_venc_vic_mode {
        { 5, &meson_hdmi_encp_mode_1080i60 },
        { 20, &meson_hdmi_encp_mode_1080i50 },
        { 32, &meson_hdmi_encp_mode_1080p24 },
+       { 33, &meson_hdmi_encp_mode_1080p50 },
        { 34, &meson_hdmi_encp_mode_1080p30 },
        { 31, &meson_hdmi_encp_mode_1080p50 },
        { 16, &meson_hdmi_encp_mode_1080p60 },
@@ -1530,10 +1532,12 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
 void meson_venc_enable_vsync(struct meson_drm *priv)
 {
        writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
+       regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
 }
 
 void meson_venc_disable_vsync(struct meson_drm *priv)
 {
+       regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), 0);
        writel_relaxed(0, priv->io_base + _REG(VENC_INTCTRL));
 }
 
index 6bcfa527c1801045569496712c904b3a26f8c518..26a0857878bfd520fe3ebe43cfa85c60534ff66a 100644 (file)
@@ -184,18 +184,18 @@ void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
        if (lut_sel == VIU_LUT_OSD_OETF) {
                writel(0, priv->io_base + _REG(addr_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
                        writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
                                priv->io_base + _REG(data_port));
 
                writel(r_map[OSD_OETF_LUT_SIZE - 1] | (g_map[0] << 16),
                        priv->io_base + _REG(data_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
                        writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
                                priv->io_base + _REG(data_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_OETF_LUT_SIZE / 2); i++)
                        writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
                                priv->io_base + _REG(data_port));
 
@@ -211,18 +211,18 @@ void meson_viu_set_osd_lut(struct meson_drm *priv, enum viu_lut_sel_e lut_sel,
        } else if (lut_sel == VIU_LUT_OSD_EOTF) {
                writel(0, priv->io_base + _REG(addr_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
                        writel(r_map[i * 2] | (r_map[i * 2 + 1] << 16),
                                priv->io_base + _REG(data_port));
 
                writel(r_map[OSD_EOTF_LUT_SIZE - 1] | (g_map[0] << 16),
                        priv->io_base + _REG(data_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
                        writel(g_map[i * 2 + 1] | (g_map[i * 2 + 2] << 16),
                                priv->io_base + _REG(data_port));
 
-               for (i = 0; i < 20; i++)
+               for (i = 0; i < (OSD_EOTF_LUT_SIZE / 2); i++)
                        writel(b_map[i * 2] | (b_map[i * 2 + 1] << 16),
                                priv->io_base + _REG(data_port));
 
index d85f0a1c158173b97bf94b251a889f31e8fff948..cebf313c6e1f9290dd8817099fb6388d25649032 100644 (file)
@@ -202,10 +202,25 @@ void rcar_du_group_put(struct rcar_du_group *rgrp)
 
 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
 {
-       struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
+       struct rcar_du_device *rcdu = rgrp->dev;
+
+       /*
+        * Group start/stop is controlled by the DRES and DEN bits of DSYSR0
+        * for the first group and DSYSR2 for the second group. On most DU
+        * instances, this maps to the first CRTC of the group, and we can just
+        * use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
+        * M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
+        * access the register directly using group read/write.
+        */
+       if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
+               struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
 
-       rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
-                                  start ? DSYSR_DEN : DSYSR_DRES);
+               rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
+                                          start ? DSYSR_DEN : DSYSR_DRES);
+       } else {
+               rcar_du_group_write(rgrp, DSYSR,
+                                   start ? DSYSR_DEN : DSYSR_DRES);
+       }
 }
 
 void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
index 71d3445ba869c85654ae3dcaf3a5460e8fadb268..07ee19573b3f0f8d65d6a64710fb1bea557b42eb 100644 (file)
@@ -274,7 +274,7 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
                break;
        case INA2XX_CURRENT:
                /* signed register, result in mA */
-               val = regval * data->current_lsb_uA;
+               val = (s16)regval * data->current_lsb_uA;
                val = DIV_ROUND_CLOSEST(val, 1000);
                break;
        case INA2XX_CALIBRATION:
@@ -491,7 +491,7 @@ static int ina2xx_probe(struct i2c_client *client,
        }
 
        data->groups[group++] = &ina2xx_group;
-       if (id->driver_data == ina226)
+       if (chip == ina226)
                data->groups[group++] = &ina226_group;
 
        hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
@@ -500,7 +500,7 @@ static int ina2xx_probe(struct i2c_client *client,
                return PTR_ERR(hwmon_dev);
 
        dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",
-                id->name, data->rshunt);
+                client->name, data->rshunt);
 
        return 0;
 }
index de46577c7d5a1711447f0f249604635260c8f958..d8fa4bea4bc8450660fc5b468c4de8d7fad1002c 100644 (file)
@@ -51,7 +51,7 @@
  */
 #define MLXREG_FAN_GET_RPM(rval, d, s) (DIV_ROUND_CLOSEST(15000000 * 100, \
                                         ((rval) + (s)) * (d)))
-#define MLXREG_FAN_GET_FAULT(val, mask) (!!((val) ^ (mask)))
+#define MLXREG_FAN_GET_FAULT(val, mask) (!((val) ^ (mask)))
 #define MLXREG_FAN_PWM_DUTY2STATE(duty)        (DIV_ROUND_CLOSEST((duty) *     \
                                         MLXREG_FAN_MAX_STATE,          \
                                         MLXREG_FAN_MAX_DUTY))
index be5ba469089531b26b0ba2d0b1866c20f3e5312b..0d0457245e7d0e19f1acad510cb5a3d295ed812f 100644 (file)
@@ -115,7 +115,6 @@ static int rpi_hwmon_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct rpi_hwmon_data *data;
-       int ret;
 
        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
        if (!data)
@@ -124,11 +123,6 @@ static int rpi_hwmon_probe(struct platform_device *pdev)
        /* Parent driver assure that firmware is correct */
        data->fw = dev_get_drvdata(dev->parent);
 
-       /* Init throttled */
-       ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED,
-                                   &data->last_throttled,
-                                   sizeof(data->last_throttled));
-
        data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "rpi_volt",
                                                               data,
                                                               &rpi_chip_info,
index 49276bbdac3ddf0dc1153cb1941cf28f0ac10ea7..1bb80f992aa8609ed6df25973548efdfdbc7fe8c 100644 (file)
@@ -1691,7 +1691,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
  * somewhere else in the code
  */
 #define SENSOR_ATTR_TEMP(index) {                                      \
-       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
+       SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 5 ? S_IWUSR : 0), \
                show_temp_mode, store_temp_mode, NOT_USED, index - 1),  \
        SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp,          \
                NULL, TEMP_READ, index - 1),                            \
index ee366199b169caa5a521c31e6a98e8ae6ecccbcf..25d43c8f1c2a869ffc10548f1d91da7049669b66 100644 (file)
@@ -767,8 +767,10 @@ static int netdevice_event(struct notifier_block *this, unsigned long event,
 
        case NETDEV_CHANGEADDR:
                cmds[0] = netdev_del_cmd;
-               cmds[1] = add_default_gid_cmd;
-               cmds[2] = add_cmd;
+               if (ndev->reg_state == NETREG_REGISTERED) {
+                       cmds[1] = add_default_gid_cmd;
+                       cmds[2] = add_cmd;
+               }
                break;
 
        case NETDEV_CHANGEUPPER:
index 2b4c5e7dd5a173c270e131016e40fcb892e04d70..676c1fd1119d80a17d4542d035a319300332842f 100644 (file)
@@ -137,15 +137,6 @@ static void ib_umem_notifier_release(struct mmu_notifier *mn,
        up_read(&per_mm->umem_rwsem);
 }
 
-static int invalidate_page_trampoline(struct ib_umem_odp *item, u64 start,
-                                     u64 end, void *cookie)
-{
-       ib_umem_notifier_start_account(item);
-       item->umem.context->invalidate_range(item, start, start + PAGE_SIZE);
-       ib_umem_notifier_end_account(item);
-       return 0;
-}
-
 static int invalidate_range_start_trampoline(struct ib_umem_odp *item,
                                             u64 start, u64 end, void *cookie)
 {
@@ -553,12 +544,13 @@ out:
                put_page(page);
 
        if (remove_existing_mapping && umem->context->invalidate_range) {
-               invalidate_page_trampoline(
+               ib_umem_notifier_start_account(umem_odp);
+               umem->context->invalidate_range(
                        umem_odp,
-                       ib_umem_start(umem) + (page_index >> umem->page_shift),
-                       ib_umem_start(umem) + ((page_index + 1) >>
-                                              umem->page_shift),
-                       NULL);
+                       ib_umem_start(umem) + (page_index << umem->page_shift),
+                       ib_umem_start(umem) +
+                               ((page_index + 1) << umem->page_shift));
+               ib_umem_notifier_end_account(umem_odp);
                ret = -EAGAIN;
        }
 
index cf22826542100f5a369a2835882fcc97e5a03d55..77f095e5fbe3887ec4293945b701adb84791f765 100644 (file)
@@ -1268,6 +1268,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
        /* Registered a new RoCE device instance to netdev */
        rc = bnxt_re_register_netdev(rdev);
        if (rc) {
+               rtnl_unlock();
                pr_err("Failed to register with netedev: %#x\n", rc);
                return -EINVAL;
        }
@@ -1466,6 +1467,7 @@ static void bnxt_re_task(struct work_struct *work)
                                "Failed to register with IB: %#x", rc);
                        bnxt_re_remove_one(rdev);
                        bnxt_re_dev_unreg(rdev);
+                       goto exit;
                }
                break;
        case NETDEV_UP:
@@ -1489,6 +1491,7 @@ static void bnxt_re_task(struct work_struct *work)
        }
        smp_mb__before_atomic();
        atomic_dec(&rdev->sched_count);
+exit:
        kfree(re_work);
 }
 
index a4c62ae23a9aeee22213b8f799e4e796ae953e1b..3beb1523e17c29c054da7ccb874912a754283d5d 100644 (file)
@@ -1756,10 +1756,9 @@ static int hns_roce_v2_set_mac(struct hns_roce_dev *hr_dev, u8 phy_port,
        return hns_roce_cmq_send(hr_dev, &desc, 1);
 }
 
-static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
-                                 unsigned long mtpt_idx)
+static int set_mtpt_pbl(struct hns_roce_v2_mpt_entry *mpt_entry,
+                       struct hns_roce_mr *mr)
 {
-       struct hns_roce_v2_mpt_entry *mpt_entry;
        struct scatterlist *sg;
        u64 page_addr;
        u64 *pages;
@@ -1767,6 +1766,53 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
        int len;
        int entry;
 
+       mpt_entry->pbl_size = cpu_to_le32(mr->pbl_size);
+       mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(mr->pbl_ba >> 3));
+       roce_set_field(mpt_entry->byte_48_mode_ba,
+                      V2_MPT_BYTE_48_PBL_BA_H_M, V2_MPT_BYTE_48_PBL_BA_H_S,
+                      upper_32_bits(mr->pbl_ba >> 3));
+
+       pages = (u64 *)__get_free_page(GFP_KERNEL);
+       if (!pages)
+               return -ENOMEM;
+
+       i = 0;
+       for_each_sg(mr->umem->sg_head.sgl, sg, mr->umem->nmap, entry) {
+               len = sg_dma_len(sg) >> PAGE_SHIFT;
+               for (j = 0; j < len; ++j) {
+                       page_addr = sg_dma_address(sg) +
+                               (j << mr->umem->page_shift);
+                       pages[i] = page_addr >> 6;
+                       /* Record the first 2 entry directly to MTPT table */
+                       if (i >= HNS_ROCE_V2_MAX_INNER_MTPT_NUM - 1)
+                               goto found;
+                       i++;
+               }
+       }
+found:
+       mpt_entry->pa0_l = cpu_to_le32(lower_32_bits(pages[0]));
+       roce_set_field(mpt_entry->byte_56_pa0_h, V2_MPT_BYTE_56_PA0_H_M,
+                      V2_MPT_BYTE_56_PA0_H_S, upper_32_bits(pages[0]));
+
+       mpt_entry->pa1_l = cpu_to_le32(lower_32_bits(pages[1]));
+       roce_set_field(mpt_entry->byte_64_buf_pa1, V2_MPT_BYTE_64_PA1_H_M,
+                      V2_MPT_BYTE_64_PA1_H_S, upper_32_bits(pages[1]));
+       roce_set_field(mpt_entry->byte_64_buf_pa1,
+                      V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M,
+                      V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S,
+                      mr->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
+
+       free_page((unsigned long)pages);
+
+       return 0;
+}
+
+static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
+                                 unsigned long mtpt_idx)
+{
+       struct hns_roce_v2_mpt_entry *mpt_entry;
+       int ret;
+
        mpt_entry = mb_buf;
        memset(mpt_entry, 0, sizeof(*mpt_entry));
 
@@ -1781,7 +1827,6 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
                       mr->pbl_ba_pg_sz + PG_SHIFT_OFFSET);
        roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M,
                       V2_MPT_BYTE_4_PD_S, mr->pd);
-       mpt_entry->byte_4_pd_hop_st = cpu_to_le32(mpt_entry->byte_4_pd_hop_st);
 
        roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RA_EN_S, 0);
        roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1);
@@ -1796,13 +1841,11 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
                     (mr->access & IB_ACCESS_REMOTE_WRITE ? 1 : 0));
        roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S,
                     (mr->access & IB_ACCESS_LOCAL_WRITE ? 1 : 0));
-       mpt_entry->byte_8_mw_cnt_en = cpu_to_le32(mpt_entry->byte_8_mw_cnt_en);
 
        roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S,
                     mr->type == MR_TYPE_MR ? 0 : 1);
        roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_INNER_PA_VLD_S,
                     1);
-       mpt_entry->byte_12_mw_pa = cpu_to_le32(mpt_entry->byte_12_mw_pa);
 
        mpt_entry->len_l = cpu_to_le32(lower_32_bits(mr->size));
        mpt_entry->len_h = cpu_to_le32(upper_32_bits(mr->size));
@@ -1813,53 +1856,9 @@ static int hns_roce_v2_write_mtpt(void *mb_buf, struct hns_roce_mr *mr,
        if (mr->type == MR_TYPE_DMA)
                return 0;
 
-       mpt_entry->pbl_size = cpu_to_le32(mr->pbl_size);
-
-       mpt_entry->pbl_ba_l = cpu_to_le32(lower_32_bits(mr->pbl_ba >> 3));
-       roce_set_field(mpt_entry->byte_48_mode_ba, V2_MPT_BYTE_48_PBL_BA_H_M,
-                      V2_MPT_BYTE_48_PBL_BA_H_S,
-                      upper_32_bits(mr->pbl_ba >> 3));
-       mpt_entry->byte_48_mode_ba = cpu_to_le32(mpt_entry->byte_48_mode_ba);
-
-       pages = (u64 *)__get_free_page(GFP_KERNEL);
-       if (!pages)
-               return -ENOMEM;
-
-       i = 0;
-       for_each_sg(mr->umem->sg_head.sgl, sg, mr->umem->nmap, entry) {
-               len = sg_dma_len(sg) >> PAGE_SHIFT;
-               for (j = 0; j < len; ++j) {
-                       page_addr = sg_dma_address(sg) +
-                                   (j << mr->umem->page_shift);
-                       pages[i] = page_addr >> 6;
-
-                       /* Record the first 2 entry directly to MTPT table */
-                       if (i >= HNS_ROCE_V2_MAX_INNER_MTPT_NUM - 1)
-                               goto found;
-                       i++;
-               }
-       }
-
-found:
-       mpt_entry->pa0_l = cpu_to_le32(lower_32_bits(pages[0]));
-       roce_set_field(mpt_entry->byte_56_pa0_h, V2_MPT_BYTE_56_PA0_H_M,
-                      V2_MPT_BYTE_56_PA0_H_S,
-                      upper_32_bits(pages[0]));
-       mpt_entry->byte_56_pa0_h = cpu_to_le32(mpt_entry->byte_56_pa0_h);
-
-       mpt_entry->pa1_l = cpu_to_le32(lower_32_bits(pages[1]));
-       roce_set_field(mpt_entry->byte_64_buf_pa1, V2_MPT_BYTE_64_PA1_H_M,
-                      V2_MPT_BYTE_64_PA1_H_S, upper_32_bits(pages[1]));
+       ret = set_mtpt_pbl(mpt_entry, mr);
 
-       free_page((unsigned long)pages);
-
-       roce_set_field(mpt_entry->byte_64_buf_pa1,
-                      V2_MPT_BYTE_64_PBL_BUF_PG_SZ_M,
-                      V2_MPT_BYTE_64_PBL_BUF_PG_SZ_S,
-                      mr->pbl_buf_pg_sz + PG_SHIFT_OFFSET);
-       mpt_entry->byte_64_buf_pa1 = cpu_to_le32(mpt_entry->byte_64_buf_pa1);
-
-       return 0;
+       return ret;
 }
 
 static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
@@ -1868,6 +1867,7 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
                                        u64 size, void *mb_buf)
 {
        struct hns_roce_v2_mpt_entry *mpt_entry = mb_buf;
+       int ret = 0;
 
        if (flags & IB_MR_REREG_PD) {
                roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M,
@@ -1880,14 +1880,14 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
                             V2_MPT_BYTE_8_BIND_EN_S,
                             (mr_access_flags & IB_ACCESS_MW_BIND ? 1 : 0));
                roce_set_bit(mpt_entry->byte_8_mw_cnt_en,
-                          V2_MPT_BYTE_8_ATOMIC_EN_S,
-                          (mr_access_flags & IB_ACCESS_REMOTE_ATOMIC ? 1 : 0));
+                            V2_MPT_BYTE_8_ATOMIC_EN_S,
+                            mr_access_flags & IB_ACCESS_REMOTE_ATOMIC ? 1 : 0);
                roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RR_EN_S,
-                            (mr_access_flags & IB_ACCESS_REMOTE_READ ? 1 : 0));
+                            mr_access_flags & IB_ACCESS_REMOTE_READ ? 1 : 0);
                roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_RW_EN_S,
-                           (mr_access_flags & IB_ACCESS_REMOTE_WRITE ? 1 : 0));
+                            mr_access_flags & IB_ACCESS_REMOTE_WRITE ? 1 : 0);
                roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S,
-                            (mr_access_flags & IB_ACCESS_LOCAL_WRITE ? 1 : 0));
+                            mr_access_flags & IB_ACCESS_LOCAL_WRITE ? 1 : 0);
        }
 
        if (flags & IB_MR_REREG_TRANS) {
@@ -1896,21 +1896,13 @@ static int hns_roce_v2_rereg_write_mtpt(struct hns_roce_dev *hr_dev,
                mpt_entry->len_l = cpu_to_le32(lower_32_bits(size));
                mpt_entry->len_h = cpu_to_le32(upper_32_bits(size));
 
-               mpt_entry->pbl_size = cpu_to_le32(mr->pbl_size);
-               mpt_entry->pbl_ba_l =
-                               cpu_to_le32(lower_32_bits(mr->pbl_ba >> 3));
-               roce_set_field(mpt_entry->byte_48_mode_ba,
-                              V2_MPT_BYTE_48_PBL_BA_H_M,
-                              V2_MPT_BYTE_48_PBL_BA_H_S,
-                              upper_32_bits(mr->pbl_ba >> 3));
-               mpt_entry->byte_48_mode_ba =
-                               cpu_to_le32(mpt_entry->byte_48_mode_ba);
-
                mr->iova = iova;
                mr->size = size;
+
+               ret = set_mtpt_pbl(mpt_entry, mr);
        }
 
-       return 0;
+       return ret;
 }
 
 static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
index e9c428071df3140685071f458abf72512381ae55..3569fda07e07f47b9286b7e1251c2716f9169203 100644 (file)
@@ -1094,31 +1094,26 @@ enum mlx5_ib_width {
        MLX5_IB_WIDTH_12X       = 1 << 4
 };
 
-static int translate_active_width(struct ib_device *ibdev, u8 active_width,
+static void translate_active_width(struct ib_device *ibdev, u8 active_width,
                                  u8 *ib_width)
 {
        struct mlx5_ib_dev *dev = to_mdev(ibdev);
-       int err = 0;
 
-       if (active_width & MLX5_IB_WIDTH_1X) {
+       if (active_width & MLX5_IB_WIDTH_1X)
                *ib_width = IB_WIDTH_1X;
-       } else if (active_width & MLX5_IB_WIDTH_2X) {
-               mlx5_ib_dbg(dev, "active_width %d is not supported by IB spec\n",
-                           (int)active_width);
-               err = -EINVAL;
-       } else if (active_width & MLX5_IB_WIDTH_4X) {
+       else if (active_width & MLX5_IB_WIDTH_4X)
                *ib_width = IB_WIDTH_4X;
-       } else if (active_width & MLX5_IB_WIDTH_8X) {
+       else if (active_width & MLX5_IB_WIDTH_8X)
                *ib_width = IB_WIDTH_8X;
-       } else if (active_width & MLX5_IB_WIDTH_12X) {
+       else if (active_width & MLX5_IB_WIDTH_12X)
                *ib_width = IB_WIDTH_12X;
-       else {
-               mlx5_ib_dbg(dev, "Invalid active_width %d\n",
+       else {
+               mlx5_ib_dbg(dev, "Invalid active_width %d, setting width to default value: 4x\n",
                            (int)active_width);
-               err = -EINVAL;
+               *ib_width = IB_WIDTH_4X;
        }
 
-       return err;
+       return;
 }
 
 static int mlx5_mtu_to_ib_mtu(int mtu)
@@ -1225,10 +1220,8 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u8 port,
        if (err)
                goto out;
 
-       err = translate_active_width(ibdev, ib_link_width_oper,
-                                    &props->active_width);
-       if (err)
-               goto out;
+       translate_active_width(ibdev, ib_link_width_oper, &props->active_width);
+
        err = mlx5_query_port_ib_proto_oper(mdev, &props->active_speed, port);
        if (err)
                goto out;
index b04eb67753261c71c036bc4269578d350dd40de4..2cc3d69ab6f64dde00ee48c82ff93c5edca697f4 100644 (file)
@@ -674,6 +674,15 @@ next_mr:
                        goto srcu_unlock;
                }
 
+               if (!mr->umem->is_odp) {
+                       mlx5_ib_dbg(dev, "skipping non ODP MR (lkey=0x%06x) in page fault handler.\n",
+                                   key);
+                       if (bytes_mapped)
+                               *bytes_mapped += bcnt;
+                       ret = 0;
+                       goto srcu_unlock;
+               }
+
                ret = pagefault_mr(dev, mr, io_virt, bcnt, bytes_mapped);
                if (ret < 0)
                        goto srcu_unlock;
@@ -735,6 +744,7 @@ next_mr:
                        head = frame;
 
                        bcnt -= frame->bcnt;
+                       offset = 0;
                }
                break;
 
index 6841c0f9237fb3c665cffce42cb501f3200897fe..3747cc681b18a54fb2a841f2539064e266ee5587 100644 (file)
@@ -2633,8 +2633,7 @@ static int to_mlx5_access_flags(struct mlx5_ib_qp *qp,
 
        if (access_flags & IB_ACCESS_REMOTE_READ)
                *hw_access_flags |= MLX5_QP_BIT_RRE;
-       if ((access_flags & IB_ACCESS_REMOTE_ATOMIC) &&
-           qp->ibqp.qp_type == IB_QPT_RC) {
+       if (access_flags & IB_ACCESS_REMOTE_ATOMIC) {
                int atomic_mode;
 
                atomic_mode = get_atomic_mode(dev, qp->ibqp.qp_type);
@@ -4678,17 +4677,18 @@ static int _mlx5_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
                        goto out;
                }
 
-               if (wr->opcode == IB_WR_LOCAL_INV ||
-                   wr->opcode == IB_WR_REG_MR) {
+               if (wr->opcode == IB_WR_REG_MR) {
                        fence = dev->umr_fence;
                        next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
-               } else if (wr->send_flags & IB_SEND_FENCE) {
-                       if (qp->next_fence)
-                               fence = MLX5_FENCE_MODE_SMALL_AND_FENCE;
-                       else
-                               fence = MLX5_FENCE_MODE_FENCE;
-               } else {
-                       fence = qp->next_fence;
+               } else  {
+                       if (wr->send_flags & IB_SEND_FENCE) {
+                               if (qp->next_fence)
+                                       fence = MLX5_FENCE_MODE_SMALL_AND_FENCE;
+                               else
+                                       fence = MLX5_FENCE_MODE_FENCE;
+                       } else {
+                               fence = qp->next_fence;
+                       }
                }
 
                switch (ibqp->qp_type) {
index 89ec0f64abfc35b64ed5058c85a054e13f3dab26..084bb4baebb50a1fe061bd3fa2be0e2deed2ae89 100644 (file)
@@ -91,13 +91,15 @@ EXPORT_SYMBOL(rvt_check_ah);
  * rvt_create_ah - create an address handle
  * @pd: the protection domain
  * @ah_attr: the attributes of the AH
+ * @udata: pointer to user's input output buffer information.
  *
  * This may be called from interrupt context.
  *
  * Return: newly allocated ah
  */
 struct ib_ah *rvt_create_ah(struct ib_pd *pd,
-                           struct rdma_ah_attr *ah_attr)
+                           struct rdma_ah_attr *ah_attr,
+                           struct ib_udata *udata)
 {
        struct rvt_ah *ah;
        struct rvt_dev_info *dev = ib_to_rvt(pd->device);
index 16105af9918908b4d6d417513560c273080465fc..25271b48a6830c5b6b962095c8fee2b33503036c 100644 (file)
@@ -51,7 +51,8 @@
 #include <rdma/rdma_vt.h>
 
 struct ib_ah *rvt_create_ah(struct ib_pd *pd,
-                           struct rdma_ah_attr *ah_attr);
+                           struct rdma_ah_attr *ah_attr,
+                           struct ib_udata *udata);
 int rvt_destroy_ah(struct ib_ah *ibah);
 int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
 int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
index 946b623ba5eb7f693469c90fdbd32c7f76bd3b2e..4ff3d98fa6a4e2b6b127d973d6b0edf9063cd474 100644 (file)
@@ -1124,7 +1124,9 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
                                         IB_MR_CHECK_SIG_STATUS, &mr_status);
                if (ret) {
                        pr_err("ib_check_mr_status failed, ret %d\n", ret);
-                       goto err;
+                       /* Not a lot we can do, return ambiguous guard error */
+                       *sector = 0;
+                       return 0x1;
                }
 
                if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) {
@@ -1152,9 +1154,6 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task,
        }
 
        return 0;
-err:
-       /* Not alot we can do here, return ambiguous guard error */
-       return 0x1;
 }
 
 void iser_err_comp(struct ib_wc *wc, const char *type)
index 55af04fa03a77e850196e82e930e3f85af7c6aa7..6c8dcb65ff031d230303604c2071797027bf11a4 100644 (file)
@@ -1441,6 +1441,9 @@ static void nic_remove(struct pci_dev *pdev)
 {
        struct nicpf *nic = pci_get_drvdata(pdev);
 
+       if (!nic)
+               return;
+
        if (nic->flags & NIC_SRIOV_ENABLED)
                pci_disable_sriov(pdev);
 
index be268dcde8fa2a5db3fd392237d583a4c5cc0d5e..f9a4e76c5a8b73799c61cb7d3a260cc50f9287ee 100644 (file)
@@ -915,10 +915,8 @@ static int hip04_mac_probe(struct platform_device *pdev)
        }
 
        ret = register_netdev(ndev);
-       if (ret) {
-               free_netdev(ndev);
+       if (ret)
                goto alloc_fail;
-       }
 
        return 0;
 
index 21c2688d63082ec25bb6f72e921d39ac3beedee8..a3f45335437c3cecde089e44c3a13a3932001960 100644 (file)
@@ -1413,7 +1413,7 @@ void __i40e_del_filter(struct i40e_vsi *vsi, struct i40e_mac_filter *f)
        }
 
        vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
-       set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->state);
+       set_bit(__I40E_MACVLAN_SYNC_PENDING, vsi->back->state);
 }
 
 /**
index add1e457886df5e40a11388738b7580bc3a2508c..433c8e688c78d5623e65fe5edefeae4cc22d67a8 100644 (file)
@@ -33,7 +33,7 @@ static int i40e_alloc_xsk_umems(struct i40e_vsi *vsi)
 }
 
 /**
- * i40e_add_xsk_umem - Store an UMEM for a certain ring/qid
+ * i40e_add_xsk_umem - Store a UMEM for a certain ring/qid
  * @vsi: Current VSI
  * @umem: UMEM to store
  * @qid: Ring/qid to associate with the UMEM
@@ -56,7 +56,7 @@ static int i40e_add_xsk_umem(struct i40e_vsi *vsi, struct xdp_umem *umem,
 }
 
 /**
- * i40e_remove_xsk_umem - Remove an UMEM for a certain ring/qid
+ * i40e_remove_xsk_umem - Remove a UMEM for a certain ring/qid
  * @vsi: Current VSI
  * @qid: Ring/qid associated with the UMEM
  **/
@@ -130,7 +130,7 @@ static void i40e_xsk_umem_dma_unmap(struct i40e_vsi *vsi, struct xdp_umem *umem)
 }
 
 /**
- * i40e_xsk_umem_enable - Enable/associate an UMEM to a certain ring/qid
+ * i40e_xsk_umem_enable - Enable/associate a UMEM to a certain ring/qid
  * @vsi: Current VSI
  * @umem: UMEM
  * @qid: Rx ring to associate UMEM to
@@ -189,7 +189,7 @@ static int i40e_xsk_umem_enable(struct i40e_vsi *vsi, struct xdp_umem *umem,
 }
 
 /**
- * i40e_xsk_umem_disable - Diassociate an UMEM from a certain ring/qid
+ * i40e_xsk_umem_disable - Disassociate a UMEM from a certain ring/qid
  * @vsi: Current VSI
  * @qid: Rx ring to associate UMEM to
  *
@@ -255,12 +255,12 @@ int i40e_xsk_umem_query(struct i40e_vsi *vsi, struct xdp_umem **umem,
 }
 
 /**
- * i40e_xsk_umem_query - Queries a certain ring/qid for its UMEM
+ * i40e_xsk_umem_setup - Enable/disassociate a UMEM to/from a ring/qid
  * @vsi: Current VSI
  * @umem: UMEM to enable/associate to a ring, or NULL to disable
  * @qid: Rx ring to (dis)associate UMEM (from)to
  *
- * This function enables or disables an UMEM to a certain ring.
+ * This function enables or disables a UMEM to a certain ring.
  *
  * Returns 0 on success, <0 on failure
  **/
@@ -276,7 +276,7 @@ int i40e_xsk_umem_setup(struct i40e_vsi *vsi, struct xdp_umem *umem,
  * @rx_ring: Rx ring
  * @xdp: xdp_buff used as input to the XDP program
  *
- * This function enables or disables an UMEM to a certain ring.
+ * This function enables or disables a UMEM to a certain ring.
  *
  * Returns any of I40E_XDP_{PASS, CONSUMED, TX, REDIR}
  **/
index c54ebedca6da9a3ddaeff1b43cde2993438c4714..c393cb2c0f1681f702a8b648f21ef49c3c8a565d 100644 (file)
@@ -842,6 +842,7 @@ s32 igb_pll_workaround_i210(struct e1000_hw *hw)
                nvm_word = E1000_INVM_DEFAULT_AL;
        tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
        igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, E1000_PHY_PLL_FREQ_PAGE);
+       phy_word = E1000_PHY_PLL_UNCONF;
        for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
                /* check current state directly from internal PHY */
                igb_read_phy_reg_82580(hw, E1000_PHY_PLL_FREQ_REG, &phy_word);
index 10dbaf4f6e808d7e2e19e6a560f11213eb1b2b87..9c42f741ed5efde3ad667bbc75d4a6b5ea5dec15 100644 (file)
@@ -2262,7 +2262,9 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
                *autoneg = false;
 
                if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
-                   hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
+                   hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 ||
+                   hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
+                   hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
                        *speed = IXGBE_LINK_SPEED_1GB_FULL;
                        return 0;
                }
index 867cddba840feb07aa93c1b58908023572951e7a..e8ca98c070f68443c6460ecb10d3eb4b3ee9a2f2 100644 (file)
@@ -1672,7 +1672,7 @@ static int lan743x_tx_napi_poll(struct napi_struct *napi, int weight)
                netif_wake_queue(adapter->netdev);
        }
 
-       if (!napi_complete_done(napi, weight))
+       if (!napi_complete(napi))
                goto done;
 
        /* enable isr */
@@ -1681,7 +1681,7 @@ static int lan743x_tx_napi_poll(struct napi_struct *napi, int weight)
        lan743x_csr_read(adapter, INT_STS);
 
 done:
-       return weight;
+       return 0;
 }
 
 static void lan743x_tx_ring_cleanup(struct lan743x_tx *tx)
@@ -1870,9 +1870,9 @@ static int lan743x_tx_open(struct lan743x_tx *tx)
        tx->vector_flags = lan743x_intr_get_vector_flags(adapter,
                                                         INT_BIT_DMA_TX_
                                                         (tx->channel_number));
-       netif_napi_add(adapter->netdev,
-                      &tx->napi, lan743x_tx_napi_poll,
-                      tx->ring_size - 1);
+       netif_tx_napi_add(adapter->netdev,
+                         &tx->napi, lan743x_tx_napi_poll,
+                         tx->ring_size - 1);
        napi_enable(&tx->napi);
 
        data = 0;
@@ -3017,6 +3017,7 @@ static const struct dev_pm_ops lan743x_pm_ops = {
 
 static const struct pci_device_id lan743x_pcidev_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7430) },
+       { PCI_DEVICE(PCI_VENDOR_ID_SMSC, PCI_DEVICE_ID_SMSC_LAN7431) },
        { 0, }
 };
 
index 0e82b6368798a2cf02cfef922b4feffa2ff779d1..2d6eea18973e8f4c8b5c733d825a5a0cc8492c39 100644 (file)
@@ -548,6 +548,7 @@ struct lan743x_adapter;
 /* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */
 #define PCI_VENDOR_ID_SMSC             PCI_VENDOR_ID_EFAR
 #define PCI_DEVICE_ID_SMSC_LAN7430     (0x7430)
+#define PCI_DEVICE_ID_SMSC_LAN7431     (0x7431)
 
 #define PCI_CONFIG_LENGTH              (0x1000)
 
index 78a638ec7c0aee931c9d56aa278430891e76562f..979f1e4bc18bfbc38946198ea6667ff516edc580 100644 (file)
@@ -6071,7 +6071,7 @@ static const char * const s_igu_fifo_error_strs[] = {
        "no error",
        "length error",
        "function disabled",
-       "VF sent command to attnetion address",
+       "VF sent command to attention address",
        "host sent prod update command",
        "read of during interrupt register while in MIMD mode",
        "access to PXP BAR reserved address",
index ef9538ee53d0db7f43eae4298dd39258b4c39122..82412691ee66bf13b488db6d61072f239d27d9c3 100644 (file)
@@ -3605,7 +3605,7 @@ static const char velocity_gstrings[][ETH_GSTRING_LEN] = {
        "tx_jumbo",
        "rx_mac_control_frames",
        "tx_mac_control_frames",
-       "rx_frame_alignement_errors",
+       "rx_frame_alignment_errors",
        "rx_long_ok",
        "rx_long_err",
        "tx_sqe_errors",
index ab33d1777132e62a141e7ca76c11ef694a6f4e63..23ee3967c166713bac24906f1705a53c8eed8d70 100644 (file)
@@ -2197,6 +2197,14 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
        new_driver->mdiodrv.driver.remove = phy_remove;
        new_driver->mdiodrv.driver.owner = owner;
 
+       /* The following works around an issue where the PHY driver doesn't bind
+        * to the device, resulting in the genphy driver being used instead of
+        * the dedicated driver. The root cause of the issue isn't known yet
+        * and seems to be in the base driver core. Once this is fixed we may
+        * remove this workaround.
+        */
+       new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
+
        retval = driver_register(&new_driver->mdiodrv.driver);
        if (retval) {
                pr_err("%s: Error %d in registering driver\n",
index e9f101c9bae2ce1d9bde5dbe0d473119ead760e6..bfbb39f935545794c151c18de29655a574fd8bcd 100644 (file)
@@ -216,9 +216,9 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                         * it just report sending a packet to the target
                         * (without actual packet transfer).
                         */
-                       dev_kfree_skb_any(skb);
                        ndev->stats.tx_packets++;
                        ndev->stats.tx_bytes += skb->len;
+                       dev_kfree_skb_any(skb);
                }
        }
 
index 7275761a1177ca9cda569bfc734bb6de3e1558e1..3d8a70d3ea9bd67c91f85c6cab38d1afbf5f25f3 100644 (file)
@@ -140,7 +140,6 @@ struct ipheth_device {
        struct usb_device *udev;
        struct usb_interface *intf;
        struct net_device *net;
-       struct sk_buff *tx_skb;
        struct urb *tx_urb;
        struct urb *rx_urb;
        unsigned char *tx_buf;
@@ -230,6 +229,7 @@ static void ipheth_rcvbulk_callback(struct urb *urb)
        case -ENOENT:
        case -ECONNRESET:
        case -ESHUTDOWN:
+       case -EPROTO:
                return;
        case 0:
                break;
@@ -281,7 +281,6 @@ static void ipheth_sndbulk_callback(struct urb *urb)
                dev_err(&dev->intf->dev, "%s: urb status: %d\n",
                __func__, status);
 
-       dev_kfree_skb_irq(dev->tx_skb);
        if (status == 0)
                netif_wake_queue(dev->net);
        else
@@ -423,7 +422,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
        if (skb->len > IPHETH_BUF_SIZE) {
                WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len);
                dev->net->stats.tx_dropped++;
-               dev_kfree_skb_irq(skb);
+               dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
 
@@ -443,12 +442,11 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net)
                dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n",
                        __func__, retval);
                dev->net->stats.tx_errors++;
-               dev_kfree_skb_irq(skb);
+               dev_kfree_skb_any(skb);
        } else {
-               dev->tx_skb = skb;
-
                dev->net->stats.tx_packets++;
                dev->net->stats.tx_bytes += skb->len;
+               dev_consume_skb_any(skb);
                netif_stop_queue(net);
        }
 
index 5a4b47958073ee4526772f35e8b5614cc3c63418..38a08805a30c64bba10519550474cac0fc83cdad 100644 (file)
@@ -579,10 +579,8 @@ int dev_pm_opp_of_add_table_indexed(struct device *dev, int index)
                 */
                count = of_count_phandle_with_args(dev->of_node,
                                                   "operating-points-v2", NULL);
-               if (count != 1)
-                       return -ENODEV;
-
-               index = 0;
+               if (count == 1)
+                       index = 0;
        }
 
        opp_table = dev_pm_opp_get_opp_table_indexed(dev, index);
index 3f4fb4dbbe33b0ca755dc547707b815a337597e9..1c69c404df1149d96ef1abe24767a96077ab199b 100644 (file)
@@ -417,7 +417,6 @@ static struct platform_driver ti_opp_supply_driver = {
        .probe = ti_opp_supply_probe,
        .driver = {
                   .name = "ti_opp_supply",
-                  .owner = THIS_MODULE,
                   .of_match_table = of_match_ptr(ti_opp_supply_of_match),
                   },
 };
index fd77e46eb3b21520f2bf155612aed0248e773884..70a006ba4d050d2d3063f6653e610372e7d2d074 100644 (file)
@@ -387,8 +387,10 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
                 * orb specified one of the unsupported formats, we defer
                 * checking for IDAWs in unsupported formats to here.
                 */
-               if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw))
+               if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw)) {
+                       kfree(p);
                        return -EOPNOTSUPP;
+               }
 
                if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw)))
                        break;
@@ -528,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
 
        ret = pfn_array_alloc_pin(pat->pat_pa, cp->mdev, ccw->cda, ccw->count);
        if (ret < 0)
-               goto out_init;
+               goto out_unpin;
 
        /* Translate this direct ccw to a idal ccw. */
        idaws = kcalloc(ret, sizeof(*idaws), GFP_DMA | GFP_KERNEL);
index f47d16b5810b9154c7b8bd852039d1cdc89b33d3..a10cec0e86eb495ffd45f3854a09e1a76bf3e598 100644 (file)
@@ -22,7 +22,7 @@
 #include "vfio_ccw_private.h"
 
 struct workqueue_struct *vfio_ccw_work_q;
-struct kmem_cache *vfio_ccw_io_region;
+static struct kmem_cache *vfio_ccw_io_region;
 
 /*
  * Helpers
@@ -134,14 +134,14 @@ static int vfio_ccw_sch_probe(struct subchannel *sch)
        if (ret)
                goto out_free;
 
-       ret = vfio_ccw_mdev_reg(sch);
-       if (ret)
-               goto out_disable;
-
        INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo);
        atomic_set(&private->avail, 1);
        private->state = VFIO_CCW_STATE_STANDBY;
 
+       ret = vfio_ccw_mdev_reg(sch);
+       if (ret)
+               goto out_disable;
+
        return 0;
 
 out_disable:
index 048665e4f13d4695ed9c85c438e7f6b36bc3f7c9..9f5a201c4c87861f6b77c6081b03a8d58d571366 100644 (file)
@@ -775,6 +775,8 @@ static int ap_device_probe(struct device *dev)
                drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
                if (!!devres != !!drvres)
                        return -ENODEV;
+               /* (re-)init queue's state machine */
+               ap_queue_reinit_state(to_ap_queue(dev));
        }
 
        /* Add queue/card to list of active queues/cards */
@@ -807,6 +809,8 @@ static int ap_device_remove(struct device *dev)
        struct ap_device *ap_dev = to_ap_dev(dev);
        struct ap_driver *ap_drv = ap_dev->drv;
 
+       if (is_queue_dev(dev))
+               ap_queue_remove(to_ap_queue(dev));
        if (ap_drv->remove)
                ap_drv->remove(ap_dev);
 
@@ -1444,10 +1448,6 @@ static void ap_scan_bus(struct work_struct *unused)
                        aq->ap_dev.device.parent = &ac->ap_dev.device;
                        dev_set_name(&aq->ap_dev.device,
                                     "%02x.%04x", id, dom);
-                       /* Start with a device reset */
-                       spin_lock_bh(&aq->lock);
-                       ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
-                       spin_unlock_bh(&aq->lock);
                        /* Register device */
                        rc = device_register(&aq->ap_dev.device);
                        if (rc) {
index 3eed1b36c876d1fde221a38e676544f2c1c3679f..bfc66e4a9de14de0fd4d4da97dedfd53f605ddea 100644 (file)
@@ -254,6 +254,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type);
 void ap_queue_remove(struct ap_queue *aq);
 void ap_queue_suspend(struct ap_device *ap_dev);
 void ap_queue_resume(struct ap_device *ap_dev);
+void ap_queue_reinit_state(struct ap_queue *aq);
 
 struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
                               int comp_device_type, unsigned int functions);
index 66f7334bcb03214307fb4f3fecebf91dbb3ba341..0aa4b3ccc948c10cbbd9ac904d6da353e341fd78 100644 (file)
@@ -718,5 +718,20 @@ void ap_queue_remove(struct ap_queue *aq)
 {
        ap_flush_queue(aq);
        del_timer_sync(&aq->timeout);
+
+       /* reset with zero, also clears irq registration */
+       spin_lock_bh(&aq->lock);
+       ap_zapq(aq->qid);
+       aq->state = AP_STATE_BORKED;
+       spin_unlock_bh(&aq->lock);
 }
 EXPORT_SYMBOL(ap_queue_remove);
+
+void ap_queue_reinit_state(struct ap_queue *aq)
+{
+       spin_lock_bh(&aq->lock);
+       aq->state = AP_STATE_RESET_START;
+       ap_wait(ap_sm_event(aq, AP_EVENT_POLL));
+       spin_unlock_bh(&aq->lock);
+}
+EXPORT_SYMBOL(ap_queue_reinit_state);
index 146f54f5cbb817a8bb3f40a7c38add038484ebc0..c50f3e86cc7487377e09211264a4d4cc43ec4b61 100644 (file)
@@ -196,7 +196,6 @@ static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
        struct ap_queue *aq = to_ap_queue(&ap_dev->device);
        struct zcrypt_queue *zq = aq->private;
 
-       ap_queue_remove(aq);
        if (zq)
                zcrypt_queue_unregister(zq);
 }
index 546f6767673481e52ee13149af1df50545e2350e..35c7c6672713b70b33959b48322de5c0254c4a29 100644 (file)
@@ -251,7 +251,6 @@ static void zcrypt_cex2c_queue_remove(struct ap_device *ap_dev)
        struct ap_queue *aq = to_ap_queue(&ap_dev->device);
        struct zcrypt_queue *zq = aq->private;
 
-       ap_queue_remove(aq);
        if (zq)
                zcrypt_queue_unregister(zq);
 }
index f9d4c6c7521d72705977a6386e0746a556e1ea8b..582ffa7e0f18793f83739978fa7143dd44ec382d 100644 (file)
@@ -275,7 +275,6 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
        struct ap_queue *aq = to_ap_queue(&ap_dev->device);
        struct zcrypt_queue *zq = aq->private;
 
-       ap_queue_remove(aq);
        if (zq)
                zcrypt_queue_unregister(zq);
 }
index 4bce5ae65a55c193ec84c0d64137adde497daf6b..254065271867146bc91db048116371ac5d3b2867 100644 (file)
@@ -4518,8 +4518,8 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
 {
        struct qeth_ipa_cmd *cmd;
        struct qeth_arp_query_info *qinfo;
-       struct qeth_snmp_cmd *snmp;
        unsigned char *data;
+       void *snmp_data;
        __u16 data_len;
 
        QETH_CARD_TEXT(card, 3, "snpcmdcb");
@@ -4527,7 +4527,6 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
        cmd = (struct qeth_ipa_cmd *) sdata;
        data = (unsigned char *)((char *)cmd - reply->offset);
        qinfo = (struct qeth_arp_query_info *) reply->param;
-       snmp = &cmd->data.setadapterparms.data.snmp;
 
        if (cmd->hdr.return_code) {
                QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code);
@@ -4540,10 +4539,15 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
                return 0;
        }
        data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data));
-       if (cmd->data.setadapterparms.hdr.seq_no == 1)
-               data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
-       else
-               data_len -= (__u16)((char *)&snmp->request - (char *)cmd);
+       if (cmd->data.setadapterparms.hdr.seq_no == 1) {
+               snmp_data = &cmd->data.setadapterparms.data.snmp;
+               data_len -= offsetof(struct qeth_ipa_cmd,
+                                    data.setadapterparms.data.snmp);
+       } else {
+               snmp_data = &cmd->data.setadapterparms.data.snmp.request;
+               data_len -= offsetof(struct qeth_ipa_cmd,
+                                    data.setadapterparms.data.snmp.request);
+       }
 
        /* check if there is enough room in userspace */
        if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
@@ -4556,16 +4560,9 @@ static int qeth_snmp_command_cb(struct qeth_card *card,
        QETH_CARD_TEXT_(card, 4, "sseqn%i",
                cmd->data.setadapterparms.hdr.seq_no);
        /*copy entries to user buffer*/
-       if (cmd->data.setadapterparms.hdr.seq_no == 1) {
-               memcpy(qinfo->udata + qinfo->udata_offset,
-                      (char *)snmp,
-                      data_len + offsetof(struct qeth_snmp_cmd, data));
-               qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
-       } else {
-               memcpy(qinfo->udata + qinfo->udata_offset,
-                      (char *)&snmp->request, data_len);
-       }
+       memcpy(qinfo->udata + qinfo->udata_offset, snmp_data, data_len);
        qinfo->udata_offset += data_len;
+
        /* check if all replies received ... */
                QETH_CARD_TEXT_(card, 4, "srtot%i",
                               cmd->data.setadapterparms.hdr.used_total);
index 3dc31627c655809eca5c11eca309de9ddcfe5b68..0c2867deb36fce48c74b92388d210371ebd1a6d0 100644 (file)
@@ -522,11 +522,11 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
                mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len);
                mtk_spi_setup_packet(master);
 
-               cnt = len / 4;
+               cnt = mdata->xfer_len / 4;
                iowrite32_rep(mdata->base + SPI_TX_DATA_REG,
                                trans->tx_buf + mdata->num_xfered, cnt);
 
-               remainder = len % 4;
+               remainder = mdata->xfer_len % 4;
                if (remainder > 0) {
                        reg_val = 0;
                        memcpy(&reg_val,
index f024c3fc3679de30c7969b28199fabcbbd562087..2fd8881fcd65c96ca76e5932bb310605a2ff1c49 100644 (file)
@@ -1540,13 +1540,26 @@ static int omap2_mcspi_remove(struct platform_device *pdev)
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:omap2_mcspi");
 
-#ifdef CONFIG_SUSPEND
-static int omap2_mcspi_suspend_noirq(struct device *dev)
+static int __maybe_unused omap2_mcspi_suspend(struct device *dev)
 {
-       return pinctrl_pm_select_sleep_state(dev);
+       struct spi_master *master = dev_get_drvdata(dev);
+       struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
+       int error;
+
+       error = pinctrl_pm_select_sleep_state(dev);
+       if (error)
+               dev_warn(mcspi->dev, "%s: failed to set pins: %i\n",
+                        __func__, error);
+
+       error = spi_master_suspend(master);
+       if (error)
+               dev_warn(mcspi->dev, "%s: master suspend failed: %i\n",
+                        __func__, error);
+
+       return pm_runtime_force_suspend(dev);
 }
 
-static int omap2_mcspi_resume_noirq(struct device *dev)
+static int __maybe_unused omap2_mcspi_resume(struct device *dev)
 {
        struct spi_master *master = dev_get_drvdata(dev);
        struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
@@ -1557,17 +1570,17 @@ static int omap2_mcspi_resume_noirq(struct device *dev)
                dev_warn(mcspi->dev, "%s: failed to set pins: %i\n",
                         __func__, error);
 
-       return 0;
-}
+       error = spi_master_resume(master);
+       if (error)
+               dev_warn(mcspi->dev, "%s: master resume failed: %i\n",
+                        __func__, error);
 
-#else
-#define omap2_mcspi_suspend_noirq      NULL
-#define omap2_mcspi_resume_noirq       NULL
-#endif
+       return pm_runtime_force_resume(dev);
+}
 
 static const struct dev_pm_ops omap2_mcspi_pm_ops = {
-       .suspend_noirq = omap2_mcspi_suspend_noirq,
-       .resume_noirq = omap2_mcspi_resume_noirq,
+       SET_SYSTEM_SLEEP_PM_OPS(omap2_mcspi_suspend,
+                               omap2_mcspi_resume)
        .runtime_resume = omap_mcspi_runtime_resume,
 };
 
index 43dea3b00c29b9dc93b6416e8e869b4f8d726c28..8a2562e3a3163378deb576daeb6129ffa03cfafe 100644 (file)
@@ -1075,8 +1075,6 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
        if (fc->ac.error < 0)
                return;
 
-       d_drop(new_dentry);
-
        inode = afs_iget(fc->vnode->vfs_inode.i_sb, fc->key,
                         newfid, newstatus, newcb, fc->cbi);
        if (IS_ERR(inode)) {
@@ -1090,7 +1088,7 @@ static void afs_vnode_new_inode(struct afs_fs_cursor *fc,
        vnode = AFS_FS_I(inode);
        set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
        afs_vnode_commit_status(fc, vnode, 0);
-       d_add(new_dentry, inode);
+       d_instantiate(new_dentry, inode);
 }
 
 /*
index d049cb4597425484d444be5e2d0b7b81b13fb116..fde6b4d4121e38532ea9ade21feb40b0a2bd09c6 100644 (file)
@@ -61,8 +61,11 @@ void afs_fileserver_probe_result(struct afs_call *call)
                afs_io_error(call, afs_io_error_fs_probe_fail);
                goto out;
        case -ECONNRESET: /* Responded, but call expired. */
+       case -ERFKILL:
+       case -EADDRNOTAVAIL:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
+       case -EHOSTDOWN:
        case -ECONNREFUSED:
        case -ETIMEDOUT:
        case -ETIME:
@@ -132,12 +135,14 @@ out:
 static int afs_do_probe_fileserver(struct afs_net *net,
                                   struct afs_server *server,
                                   struct key *key,
-                                  unsigned int server_index)
+                                  unsigned int server_index,
+                                  struct afs_error *_e)
 {
        struct afs_addr_cursor ac = {
                .index = 0,
        };
-       int ret;
+       bool in_progress = false;
+       int err;
 
        _enter("%pU", &server->uuid);
 
@@ -151,15 +156,17 @@ static int afs_do_probe_fileserver(struct afs_net *net,
        server->probe.rtt = UINT_MAX;
 
        for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
-               ret = afs_fs_get_capabilities(net, server, &ac, key, server_index,
+               err = afs_fs_get_capabilities(net, server, &ac, key, server_index,
                                              true);
-               if (ret != -EINPROGRESS) {
-                       afs_fs_probe_done(server);
-                       return ret;
-               }
+               if (err == -EINPROGRESS)
+                       in_progress = true;
+               else
+                       afs_prioritise_error(_e, err, ac.abort_code);
        }
 
-       return 0;
+       if (!in_progress)
+               afs_fs_probe_done(server);
+       return in_progress;
 }
 
 /*
@@ -169,21 +176,23 @@ int afs_probe_fileservers(struct afs_net *net, struct key *key,
                          struct afs_server_list *list)
 {
        struct afs_server *server;
-       int i, ret;
+       struct afs_error e;
+       bool in_progress = false;
+       int i;
 
+       e.error = 0;
+       e.responded = false;
        for (i = 0; i < list->nr_servers; i++) {
                server = list->servers[i].server;
                if (test_bit(AFS_SERVER_FL_PROBED, &server->flags))
                        continue;
 
-               if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags)) {
-                       ret = afs_do_probe_fileserver(net, server, key, i);
-                       if (ret)
-                               return ret;
-               }
+               if (!test_and_set_bit_lock(AFS_SERVER_FL_PROBING, &server->flags) &&
+                   afs_do_probe_fileserver(net, server, key, i, &e))
+                       in_progress = true;
        }
 
-       return 0;
+       return in_progress ? 0 : e.error;
 }
 
 /*
index 4c6d8e1112c2b716ef788afbb31635150af3f87b..6b17d362041426967dd5fdc875a80c46d4e30742 100644 (file)
@@ -382,7 +382,7 @@ void afs_zap_data(struct afs_vnode *vnode)
 int afs_validate(struct afs_vnode *vnode, struct key *key)
 {
        time64_t now = ktime_get_real_seconds();
-       bool valid = false;
+       bool valid;
        int ret;
 
        _enter("{v={%llx:%llu} fl=%lx},%x",
@@ -402,15 +402,21 @@ int afs_validate(struct afs_vnode *vnode, struct key *key)
                        vnode->cb_v_break = vnode->volume->cb_v_break;
                        valid = false;
                } else if (vnode->status.type == AFS_FTYPE_DIR &&
-                          test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) &&
-                          vnode->cb_expires_at - 10 > now) {
-                       valid = true;
-               } else if (!test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) &&
-                          vnode->cb_expires_at - 10 > now) {
+                          (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags) ||
+                           vnode->cb_expires_at - 10 <= now)) {
+                       valid = false;
+               } else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags) ||
+                          vnode->cb_expires_at - 10 <= now) {
+                       valid = false;
+               } else {
                        valid = true;
                }
        } else if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
                valid = true;
+       } else {
+               vnode->cb_s_break = vnode->cb_interest->server->cb_s_break;
+               vnode->cb_v_break = vnode->volume->cb_v_break;
+               valid = false;
        }
 
        read_sequnlock_excl(&vnode->cb_lock);
index 5da3b09b751867bc9c0bbb8c23b362fbab942a93..8871b9e8645f15ce0963745813c6de62cc8ea786 100644 (file)
@@ -695,6 +695,14 @@ struct afs_interface {
        unsigned        mtu;            /* MTU of interface */
 };
 
+/*
+ * Error prioritisation and accumulation.
+ */
+struct afs_error {
+       short   error;                  /* Accumulated error */
+       bool    responded;              /* T if server responded */
+};
+
 /*
  * Cursor for iterating over a server's address list.
  */
@@ -1015,6 +1023,7 @@ static inline void __afs_stat(atomic_t *s)
  * misc.c
  */
 extern int afs_abort_to_error(u32);
+extern void afs_prioritise_error(struct afs_error *, int, u32);
 
 /*
  * mntpt.c
index 700a5fa7f4ece2151c68f87ee58bd6d2e8e97dc3..bbb1fd51b019ead4d6cd5aeee6b26861dd73fe04 100644 (file)
@@ -118,3 +118,55 @@ int afs_abort_to_error(u32 abort_code)
        default:                return -EREMOTEIO;
        }
 }
+
+/*
+ * Select the error to report from a set of errors.
+ */
+void afs_prioritise_error(struct afs_error *e, int error, u32 abort_code)
+{
+       switch (error) {
+       case 0:
+               return;
+       default:
+               if (e->error == -ETIMEDOUT ||
+                   e->error == -ETIME)
+                       return;
+       case -ETIMEDOUT:
+       case -ETIME:
+               if (e->error == -ENOMEM ||
+                   e->error == -ENONET)
+                       return;
+       case -ENOMEM:
+       case -ENONET:
+               if (e->error == -ERFKILL)
+                       return;
+       case -ERFKILL:
+               if (e->error == -EADDRNOTAVAIL)
+                       return;
+       case -EADDRNOTAVAIL:
+               if (e->error == -ENETUNREACH)
+                       return;
+       case -ENETUNREACH:
+               if (e->error == -EHOSTUNREACH)
+                       return;
+       case -EHOSTUNREACH:
+               if (e->error == -EHOSTDOWN)
+                       return;
+       case -EHOSTDOWN:
+               if (e->error == -ECONNREFUSED)
+                       return;
+       case -ECONNREFUSED:
+               if (e->error == -ECONNRESET)
+                       return;
+       case -ECONNRESET: /* Responded, but call expired. */
+               if (e->responded)
+                       return;
+               e->error = error;
+               return;
+
+       case -ECONNABORTED:
+               e->responded = true;
+               e->error = afs_abort_to_error(abort_code);
+               return;
+       }
+}
index 00504254c1c24b6186ec676edcfd1fdcdfffbc63..c3ae324781f846b8122b6b0a80085efaafdcaaba 100644 (file)
@@ -136,7 +136,8 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
        struct afs_addr_list *alist;
        struct afs_server *server;
        struct afs_vnode *vnode = fc->vnode;
-       u32 rtt, abort_code;
+       struct afs_error e;
+       u32 rtt;
        int error = fc->ac.error, i;
 
        _enter("%lx[%d],%lx[%d],%d,%d",
@@ -306,8 +307,11 @@ bool afs_select_fileserver(struct afs_fs_cursor *fc)
                if (fc->error != -EDESTADDRREQ)
                        goto iterate_address;
                /* Fall through */
+       case -ERFKILL:
+       case -EADDRNOTAVAIL:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
+       case -EHOSTDOWN:
        case -ECONNREFUSED:
                _debug("no conn");
                fc->error = error;
@@ -446,50 +450,15 @@ no_more_servers:
        if (fc->flags & AFS_FS_CURSOR_VBUSY)
                goto restart_from_beginning;
 
-       abort_code = 0;
-       error = -EDESTADDRREQ;
+       e.error = -EDESTADDRREQ;
+       e.responded = false;
        for (i = 0; i < fc->server_list->nr_servers; i++) {
                struct afs_server *s = fc->server_list->servers[i].server;
-               int probe_error = READ_ONCE(s->probe.error);
 
-               switch (probe_error) {
-               case 0:
-                       continue;
-               default:
-                       if (error == -ETIMEDOUT ||
-                           error == -ETIME)
-                               continue;
-               case -ETIMEDOUT:
-               case -ETIME:
-                       if (error == -ENOMEM ||
-                           error == -ENONET)
-                               continue;
-               case -ENOMEM:
-               case -ENONET:
-                       if (error == -ENETUNREACH)
-                               continue;
-               case -ENETUNREACH:
-                       if (error == -EHOSTUNREACH)
-                               continue;
-               case -EHOSTUNREACH:
-                       if (error == -ECONNREFUSED)
-                               continue;
-               case -ECONNREFUSED:
-                       if (error == -ECONNRESET)
-                               continue;
-               case -ECONNRESET: /* Responded, but call expired. */
-                       if (error == -ECONNABORTED)
-                               continue;
-               case -ECONNABORTED:
-                       abort_code = s->probe.abort_code;
-                       error = probe_error;
-                       continue;
-               }
+               afs_prioritise_error(&e, READ_ONCE(s->probe.error),
+                                    s->probe.abort_code);
        }
 
-       if (error == -ECONNABORTED)
-               error = afs_abort_to_error(abort_code);
-
 failed_set_error:
        fc->error = error;
 failed:
@@ -553,8 +522,11 @@ bool afs_select_current_fileserver(struct afs_fs_cursor *fc)
                _leave(" = f [abort]");
                return false;
 
+       case -ERFKILL:
+       case -EADDRNOTAVAIL:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
+       case -EHOSTDOWN:
        case -ECONNREFUSED:
        case -ETIMEDOUT:
        case -ETIME:
@@ -633,6 +605,7 @@ int afs_end_vnode_operation(struct afs_fs_cursor *fc)
        struct afs_net *net = afs_v2net(fc->vnode);
 
        if (fc->error == -EDESTADDRREQ ||
+           fc->error == -EADDRNOTAVAIL ||
            fc->error == -ENETUNREACH ||
            fc->error == -EHOSTUNREACH)
                afs_dump_edestaddrreq(fc);
index c0f616bd70cba33f292e7c7cbb9d3c4e3e310f21..f0b032976487cd5bde632b171ebaf858eb11a52c 100644 (file)
@@ -61,8 +61,11 @@ void afs_vlserver_probe_result(struct afs_call *call)
                afs_io_error(call, afs_io_error_vl_probe_fail);
                goto out;
        case -ECONNRESET: /* Responded, but call expired. */
+       case -ERFKILL:
+       case -EADDRNOTAVAIL:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
+       case -EHOSTDOWN:
        case -ECONNREFUSED:
        case -ETIMEDOUT:
        case -ETIME:
@@ -129,15 +132,17 @@ out:
  * Probe all of a vlserver's addresses to find out the best route and to
  * query its capabilities.
  */
-static int afs_do_probe_vlserver(struct afs_net *net,
-                                struct afs_vlserver *server,
-                                struct key *key,
-                                unsigned int server_index)
+static bool afs_do_probe_vlserver(struct afs_net *net,
+                                 struct afs_vlserver *server,
+                                 struct key *key,
+                                 unsigned int server_index,
+                                 struct afs_error *_e)
 {
        struct afs_addr_cursor ac = {
                .index = 0,
        };
-       int ret;
+       bool in_progress = false;
+       int err;
 
        _enter("%s", server->name);
 
@@ -151,15 +156,17 @@ static int afs_do_probe_vlserver(struct afs_net *net,
        server->probe.rtt = UINT_MAX;
 
        for (ac.index = 0; ac.index < ac.alist->nr_addrs; ac.index++) {
-               ret = afs_vl_get_capabilities(net, &ac, key, server,
+               err = afs_vl_get_capabilities(net, &ac, key, server,
                                              server_index, true);
-               if (ret != -EINPROGRESS) {
-                       afs_vl_probe_done(server);
-                       return ret;
-               }
+               if (err == -EINPROGRESS)
+                       in_progress = true;
+               else
+                       afs_prioritise_error(_e, err, ac.abort_code);
        }
 
-       return 0;
+       if (!in_progress)
+               afs_vl_probe_done(server);
+       return in_progress;
 }
 
 /*
@@ -169,21 +176,23 @@ int afs_send_vl_probes(struct afs_net *net, struct key *key,
                       struct afs_vlserver_list *vllist)
 {
        struct afs_vlserver *server;
-       int i, ret;
+       struct afs_error e;
+       bool in_progress = false;
+       int i;
 
+       e.error = 0;
+       e.responded = false;
        for (i = 0; i < vllist->nr_servers; i++) {
                server = vllist->servers[i].server;
                if (test_bit(AFS_VLSERVER_FL_PROBED, &server->flags))
                        continue;
 
-               if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags)) {
-                       ret = afs_do_probe_vlserver(net, server, key, i);
-                       if (ret)
-                               return ret;
-               }
+               if (!test_and_set_bit_lock(AFS_VLSERVER_FL_PROBING, &server->flags) &&
+                   afs_do_probe_vlserver(net, server, key, i, &e))
+                       in_progress = true;
        }
 
-       return 0;
+       return in_progress ? 0 : e.error;
 }
 
 /*
index b64a284b99d272e46a75d35bad5514580e90a132..7adde83a06482b56c555c18c3629c335a2315397 100644 (file)
@@ -71,8 +71,9 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
 {
        struct afs_addr_list *alist;
        struct afs_vlserver *vlserver;
+       struct afs_error e;
        u32 rtt;
-       int error = vc->ac.error, abort_code, i;
+       int error = vc->ac.error, i;
 
        _enter("%lx[%d],%lx[%d],%d,%d",
               vc->untried, vc->index,
@@ -119,8 +120,11 @@ bool afs_select_vlserver(struct afs_vl_cursor *vc)
                        goto failed;
                }
 
+       case -ERFKILL:
+       case -EADDRNOTAVAIL:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
+       case -EHOSTDOWN:
        case -ECONNREFUSED:
        case -ETIMEDOUT:
        case -ETIME:
@@ -235,50 +239,15 @@ no_more_servers:
        if (vc->flags & AFS_VL_CURSOR_RETRY)
                goto restart_from_beginning;
 
-       abort_code = 0;
-       error = -EDESTADDRREQ;
+       e.error = -EDESTADDRREQ;
+       e.responded = false;
        for (i = 0; i < vc->server_list->nr_servers; i++) {
                struct afs_vlserver *s = vc->server_list->servers[i].server;
-               int probe_error = READ_ONCE(s->probe.error);
 
-               switch (probe_error) {
-               case 0:
-                       continue;
-               default:
-                       if (error == -ETIMEDOUT ||
-                           error == -ETIME)
-                               continue;
-               case -ETIMEDOUT:
-               case -ETIME:
-                       if (error == -ENOMEM ||
-                           error == -ENONET)
-                               continue;
-               case -ENOMEM:
-               case -ENONET:
-                       if (error == -ENETUNREACH)
-                               continue;
-               case -ENETUNREACH:
-                       if (error == -EHOSTUNREACH)
-                               continue;
-               case -EHOSTUNREACH:
-                       if (error == -ECONNREFUSED)
-                               continue;
-               case -ECONNREFUSED:
-                       if (error == -ECONNRESET)
-                               continue;
-               case -ECONNRESET: /* Responded, but call expired. */
-                       if (error == -ECONNABORTED)
-                               continue;
-               case -ECONNABORTED:
-                       abort_code = s->probe.abort_code;
-                       error = probe_error;
-                       continue;
-               }
+               afs_prioritise_error(&e, READ_ONCE(s->probe.error),
+                                    s->probe.abort_code);
        }
 
-       if (error == -ECONNABORTED)
-               error = afs_abort_to_error(abort_code);
-
 failed_set_error:
        vc->error = error;
 failed:
@@ -341,6 +310,7 @@ int afs_end_vlserver_operation(struct afs_vl_cursor *vc)
        struct afs_net *net = vc->cell->net;
 
        if (vc->error == -EDESTADDRREQ ||
+           vc->error == -EADDRNOTAVAIL ||
            vc->error == -ENETUNREACH ||
            vc->error == -EHOSTUNREACH)
                afs_vl_dump_edestaddrreq(vc);
index 301e6314183b66756077fed9e37630cc5436ff40..97f9835929256bfd6027d6958e14fb3ec64d34da 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1436,6 +1436,7 @@ static int aio_prep_rw(struct kiocb *req, struct iocb *iocb)
                ret = ioprio_check_cap(iocb->aio_reqprio);
                if (ret) {
                        pr_debug("aio ioprio check cap error: %d\n", ret);
+                       fput(req->ki_filp);
                        return ret;
                }
 
index 3f0b6d1936e8ecd05dc0bf4957bb6aa691204dd4..6d776717d8b39b566e6ec14f479648ad6f788905 100644 (file)
@@ -477,9 +477,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
        int mirror_num = 0;
        int failed_mirror = 0;
 
-       clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
        io_tree = &BTRFS_I(fs_info->btree_inode)->io_tree;
        while (1) {
+               clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
                ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE,
                                               mirror_num);
                if (!ret) {
@@ -493,15 +493,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
                                break;
                }
 
-               /*
-                * This buffer's crc is fine, but its contents are corrupted, so
-                * there is no reason to read the other copies, they won't be
-                * any less wrong.
-                */
-               if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) ||
-                   ret == -EUCLEAN)
-                       break;
-
                num_copies = btrfs_num_copies(fs_info,
                                              eb->start, eb->len);
                if (num_copies == 1)
index a3c22e16509b3067e65e86f1b98d2d9e9e84d99a..58e93bce30362dc0584c212ba18822ed13fde723 100644 (file)
@@ -2088,6 +2088,30 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 
        atomic_inc(&root->log_batch);
 
+       /*
+        * Before we acquired the inode's lock, someone may have dirtied more
+        * pages in the target range. We need to make sure that writeback for
+        * any such pages does not start while we are logging the inode, because
+        * if it does, any of the following might happen when we are not doing a
+        * full inode sync:
+        *
+        * 1) We log an extent after its writeback finishes but before its
+        *    checksums are added to the csum tree, leading to -EIO errors
+        *    when attempting to read the extent after a log replay.
+        *
+        * 2) We can end up logging an extent before its writeback finishes.
+        *    Therefore after the log replay we will have a file extent item
+        *    pointing to an unwritten extent (and no data checksums as well).
+        *
+        * So trigger writeback for any eventual new dirty pages and then we
+        * wait for all ordered extents to complete below.
+        */
+       ret = start_ordered_ops(inode, start, end);
+       if (ret) {
+               inode_unlock(inode);
+               goto out;
+       }
+
        /*
         * We have to do this here to avoid the priority inversion of waiting on
         * IO of a lower priority task while holding a transaciton open.
index 45868fd76209024dc2cfc790801ffac9133a3ef1..f70825af6438e9c48ebe782f6b8049d27ae807fc 100644 (file)
@@ -2659,7 +2659,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
        int i;
        u64 *i_qgroups;
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct btrfs_root *quota_root = fs_info->quota_root;
+       struct btrfs_root *quota_root;
        struct btrfs_qgroup *srcgroup;
        struct btrfs_qgroup *dstgroup;
        u32 level_size = 0;
@@ -2669,6 +2669,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
        if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
                goto out;
 
+       quota_root = fs_info->quota_root;
        if (!quota_root) {
                ret = -EINVAL;
                goto out;
index 924116f654a110cb9e23a878002bed0ae967029e..a3f75b8926d4474aa1093ffdd852d422b853e2d2 100644 (file)
@@ -3959,6 +3959,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
 restart:
                if (update_backref_cache(trans, &rc->backref_cache)) {
                        btrfs_end_transaction(trans);
+                       trans = NULL;
                        continue;
                }
 
index 094cc1444a90caaf0a597bd6c4a16ae265462701..5be83b5a1b43121234c6d0edda9e1c0566f30132 100644 (file)
@@ -3340,7 +3340,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m)
        kfree(m);
 }
 
-static void tail_append_pending_moves(struct pending_dir_move *moves,
+static void tail_append_pending_moves(struct send_ctx *sctx,
+                                     struct pending_dir_move *moves,
                                      struct list_head *stack)
 {
        if (list_empty(&moves->list)) {
@@ -3351,6 +3352,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves,
                list_add_tail(&moves->list, stack);
                list_splice_tail(&list, stack);
        }
+       if (!RB_EMPTY_NODE(&moves->node)) {
+               rb_erase(&moves->node, &sctx->pending_dir_moves);
+               RB_CLEAR_NODE(&moves->node);
+       }
 }
 
 static int apply_children_dir_moves(struct send_ctx *sctx)
@@ -3365,7 +3370,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
                return 0;
 
        INIT_LIST_HEAD(&stack);
-       tail_append_pending_moves(pm, &stack);
+       tail_append_pending_moves(sctx, pm, &stack);
 
        while (!list_empty(&stack)) {
                pm = list_first_entry(&stack, struct pending_dir_move, list);
@@ -3376,7 +3381,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
                        goto out;
                pm = get_pending_dir_moves(sctx, parent_ino);
                if (pm)
-                       tail_append_pending_moves(pm, &stack);
+                       tail_append_pending_moves(sctx, pm, &stack);
        }
        return 0;
 
index cbc9d0d2c12de42786da57c41ebbc9f0364ffabd..645fc81e2a948eab03431a08c0c4b062ce7fd25e 100644 (file)
@@ -2237,6 +2237,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
        vol = memdup_user((void __user *)arg, sizeof(*vol));
        if (IS_ERR(vol))
                return PTR_ERR(vol);
+       vol->name[BTRFS_PATH_NAME_MAX] = '\0';
 
        switch (cmd) {
        case BTRFS_IOC_SCAN_DEV:
index 645158dc33f1fc86bfcca570361002c540068584..c69927bed4effd6002f2021ca66c1b641acebc85 100644 (file)
@@ -77,7 +77,7 @@ static bool dentry_connected(struct dentry *dentry)
                struct dentry *parent = dget_parent(dentry);
 
                dput(dentry);
-               if (IS_ROOT(dentry)) {
+               if (dentry == parent) {
                        dput(parent);
                        return false;
                }
@@ -147,6 +147,7 @@ static struct dentry *reconnect_one(struct vfsmount *mnt,
        tmp = lookup_one_len_unlocked(nbuf, parent, strlen(nbuf));
        if (IS_ERR(tmp)) {
                dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
+               err = PTR_ERR(tmp);
                goto out_err;
        }
        if (tmp != dentry) {
index cb91baa4275d8150664e05d8a1877ca87fca4ff9..eb11502e3fcd4f10e67fdafdf4f9e7e06e04a5b5 100644 (file)
@@ -892,6 +892,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
        if (sb->s_magic != EXT2_SUPER_MAGIC)
                goto cantfind_ext2;
 
+       opts.s_mount_opt = 0;
        /* Set defaults before we parse the mount options */
        def_mount_opts = le32_to_cpu(es->s_default_mount_opts);
        if (def_mount_opts & EXT2_DEFM_DEBUG)
index 62d9a659a8ff4e7a3a9556449e35fecc25612e43..dd8f10db82e992da8b8f4fb37699d7bf4a87cf4d 100644 (file)
@@ -612,9 +612,9 @@ skip_replace:
        }
 
 cleanup:
-       brelse(bh);
        if (!(bh && header == HDR(bh)))
                kfree(header);
+       brelse(bh);
        up_write(&EXT2_I(inode)->xattr_sem);
 
        return error;
index ffcff6516e89cccfcbbc138a6d7331e4ca9fb63b..e02a9039b5ea4410d3b3a986d7f4b6566e196eff 100644 (file)
@@ -816,17 +816,14 @@ static int ramoops_probe(struct platform_device *pdev)
 
        cxt->pstore.data = cxt;
        /*
-        * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we
-        * have to handle dumps, we must have at least record_size buffer. And
-        * for ftrace, bufsize is irrelevant (if bufsize is 0, buf will be
-        * ZERO_SIZE_PTR).
+        * Since bufsize is only used for dmesg crash dumps, it
+        * must match the size of the dprz record (after PRZ header
+        * and ECC bytes have been accounted for).
         */
-       if (cxt->console_size)
-               cxt->pstore.bufsize = 1024; /* LOG_LINE_MAX */
-       cxt->pstore.bufsize = max(cxt->record_size, cxt->pstore.bufsize);
-       cxt->pstore.buf = kmalloc(cxt->pstore.bufsize, GFP_KERNEL);
+       cxt->pstore.bufsize = cxt->dprzs[0]->buffer_size;
+       cxt->pstore.buf = kzalloc(cxt->pstore.bufsize, GFP_KERNEL);
        if (!cxt->pstore.buf) {
-               pr_err("cannot allocate pstore buffer\n");
+               pr_err("cannot allocate pstore crash dump buffer\n");
                err = -ENOMEM;
                goto fail_clear;
        }
index 499a20a5a0107f3ca8942485a7a5b3bc58737793..273736f41be386c9f466c5512bd395732fade3aa 100644 (file)
@@ -275,7 +275,7 @@ static int __sysv_write_inode(struct inode *inode, int wait)
                 }
         }
        brelse(bh);
-       return 0;
+       return err;
 }
 
 int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
index 8f2f56d9a1bbfb8b110812d45167ce7e7b456099..e3d684ea320303630f4a75135ed4e4bcc408484c 100644 (file)
@@ -827,16 +827,20 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
 
 
        ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32);
-       if (ret < 0)
-               goto out_bh;
-
-       strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
+       if (ret < 0) {
+               strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName");
+               pr_warn("incorrect volume identification, setting to "
+                       "'InvalidName'\n");
+       } else {
+               strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret);
+       }
        udf_debug("volIdent[] = '%s'\n", UDF_SB(sb)->s_volume_ident);
 
        ret = udf_dstrCS0toChar(sb, outstr, 127, pvoldesc->volSetIdent, 128);
-       if (ret < 0)
+       if (ret < 0) {
+               ret = 0;
                goto out_bh;
-
+       }
        outstr[ret] = 0;
        udf_debug("volSetIdent[] = '%s'\n", outstr);
 
index 45234791fec281f027cc05b97d9364384d8bc7b8..5fcfa96463ebb820cef33b83460fc8d1a9bea8b2 100644 (file)
@@ -351,6 +351,11 @@ try_again:
        return u_len;
 }
 
+/*
+ * Convert CS0 dstring to output charset. Warning: This function may truncate
+ * input string if it is too long as it is used for informational strings only
+ * and it is better to truncate the string than to refuse mounting a media.
+ */
 int udf_dstrCS0toChar(struct super_block *sb, uint8_t *utf_o, int o_len,
                      const uint8_t *ocu_i, int i_len)
 {
@@ -359,9 +364,12 @@ int udf_dstrCS0toChar(struct super_block *sb, uint8_t *utf_o, int o_len,
        if (i_len > 0) {
                s_len = ocu_i[i_len - 1];
                if (s_len >= i_len) {
-                       pr_err("incorrect dstring lengths (%d/%d)\n",
-                              s_len, i_len);
-                       return -EINVAL;
+                       pr_warn("incorrect dstring lengths (%d/%d),"
+                               " truncating\n", s_len, i_len);
+                       s_len = i_len - 1;
+                       /* 2-byte encoding? Need to round properly... */
+                       if (ocu_i[0] == 16)
+                               s_len -= (s_len - 1) & 2;
                }
        }
 
index de629b706d1d7dda246819ed37109f098c05785e..448dcc448f1fe59cb14de60969f71f8ba6c35278 100644 (file)
@@ -866,6 +866,10 @@ void bpf_jit_binary_free(struct bpf_binary_header *hdr);
 
 void bpf_jit_free(struct bpf_prog *fp);
 
+int bpf_jit_get_func_addr(const struct bpf_prog *prog,
+                         const struct bpf_insn *insn, bool extra_pass,
+                         u64 *func_addr, bool *func_addr_fixed);
+
 struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *fp);
 void bpf_jit_prog_release_other(struct bpf_prog *fp, struct bpf_prog *fp_other);
 
index a397907e8d727481cfb933e7a7c5e80ca194b0d7..dd16e8218db3a7a9cb3988b973ae500f683cd076 100644 (file)
@@ -777,8 +777,8 @@ struct ftrace_ret_stack {
 extern void return_to_handler(void);
 
 extern int
-ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
-                        unsigned long frame_pointer, unsigned long *retp);
+function_graph_enter(unsigned long ret, unsigned long func,
+                    unsigned long frame_pointer, unsigned long *retp);
 
 unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
                                    unsigned long ret, unsigned long *retp);
index dbff9ff28f2c4596dfb08baed65d3655cfbc9866..34e17e6f894290f161d5e734e6fb2f9dfb0c148e 100644 (file)
@@ -2473,14 +2473,15 @@ struct mlx5_ifc_xrc_srqc_bits {
 
        u8         wq_signature[0x1];
        u8         cont_srq[0x1];
-       u8         dbr_umem_valid[0x1];
+       u8         reserved_at_22[0x1];
        u8         rlky[0x1];
        u8         basic_cyclic_rcv_wqe[0x1];
        u8         log_rq_stride[0x3];
        u8         xrcd[0x18];
 
        u8         page_offset[0x6];
-       u8         reserved_at_46[0x2];
+       u8         reserved_at_46[0x1];
+       u8         dbr_umem_valid[0x1];
        u8         cqn[0x18];
 
        u8         reserved_at_60[0x20];
@@ -6689,9 +6690,12 @@ struct mlx5_ifc_create_xrc_srq_in_bits {
 
        struct mlx5_ifc_xrc_srqc_bits xrc_srq_context_entry;
 
-       u8         reserved_at_280[0x40];
+       u8         reserved_at_280[0x60];
+
        u8         xrc_srq_umem_valid[0x1];
-       u8         reserved_at_2c1[0x5bf];
+       u8         reserved_at_2e1[0x1f];
+
+       u8         reserved_at_300[0x580];
 
        u8         pas[0][0x40];
 };
index b8d95564bd53481acf0bd78b15a140e8ac761776..14edb795ab43045939f9976105cd9060603ea566 100644 (file)
@@ -21,6 +21,19 @@ struct nf_ct_gre_keymap {
        struct nf_conntrack_tuple tuple;
 };
 
+enum grep_conntrack {
+       GRE_CT_UNREPLIED,
+       GRE_CT_REPLIED,
+       GRE_CT_MAX
+};
+
+struct netns_proto_gre {
+       struct nf_proto_net     nf;
+       rwlock_t                keymap_lock;
+       struct list_head        keymap_list;
+       unsigned int            gre_timeouts[GRE_CT_MAX];
+};
+
 /* add new tuple->key_reply pair to keymap */
 int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
                         struct nf_conntrack_tuple *t);
index a15bc4d487528f4f4301fdb9f30d465799637652..30fcec375a3af2d8b0ee305b7c540a15080847d2 100644 (file)
@@ -90,7 +90,10 @@ struct pstore_record {
  *
  * @buf_lock:  spinlock to serialize access to @buf
  * @buf:       preallocated crash dump buffer
- * @bufsize:   size of @buf available for crash dump writes
+ * @bufsize:   size of @buf available for crash dump bytes (must match
+ *             smallest number of bytes available for writing to a
+ *             backend entry, since compressed bytes don't take kindly
+ *             to being truncated)
  *
  * @read_mutex:        serializes @open, @read, @close, and @erase callbacks
  * @flags:     bitfield of frontends the backend can accept writes for
index a51c13c2b1a0316b00f928bc9e5afaa2ec949d83..d6183a55e8eb165acdb8ef9ee32126d80e007029 100644 (file)
@@ -1116,6 +1116,7 @@ struct task_struct {
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        /* Index of current stored address in ret_stack: */
        int                             curr_ret_stack;
+       int                             curr_ret_depth;
 
        /* Stack of return addresses for return function tracing: */
        struct ftrace_ret_stack         *ret_stack;
index 40b0b4c1bf7b89db225d94a539b025aa4bd2f9de..df20f8bdbfa30950f6c1dc2f0addf35f67b4eb2a 100644 (file)
@@ -83,8 +83,8 @@ static inline int ptrace_report_syscall(struct pt_regs *regs)
  * tracehook_report_syscall_entry - task is about to attempt a system call
  * @regs:              user register state of current task
  *
- * This will be called if %TIF_SYSCALL_TRACE has been set, when the
- * current task has just entered the kernel for a system call.
+ * This will be called if %TIF_SYSCALL_TRACE or %TIF_SYSCALL_EMU have been set,
+ * when the current task has just entered the kernel for a system call.
  * Full user register state is available here.  Changing the values
  * in @regs can affect the system call number and arguments to be tried.
  * It is safe to block here, preventing the system call from beginning.
index 538ba1a58f5b25c13a51d96da996a058e9511dde..e9de8ad0bad748e9d74e0af0d851568f6378be5c 100644 (file)
@@ -166,7 +166,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
                struct tracepoint_func *it_func_ptr;                    \
                void *it_func;                                          \
                void *__data;                                           \
-               int __maybe_unused idx = 0;                             \
+               int __maybe_unused __idx = 0;                           \
                                                                        \
                if (!(cond))                                            \
                        return;                                         \
@@ -182,7 +182,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
                 * doesn't work from the idle path.                     \
                 */                                                     \
                if (rcuidle) {                                          \
-                       idx = srcu_read_lock_notrace(&tracepoint_srcu); \
+                       __idx = srcu_read_lock_notrace(&tracepoint_srcu);\
                        rcu_irq_enter_irqson();                         \
                }                                                       \
                                                                        \
@@ -198,7 +198,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
                                                                        \
                if (rcuidle) {                                          \
                        rcu_irq_exit_irqson();                          \
-                       srcu_read_unlock_notrace(&tracepoint_srcu, idx);\
+                       srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\
                }                                                       \
                                                                        \
                preempt_enable_notrace();                               \
index cd24be4c4a99bd633f5718c822920f1aa44b7f12..13d55206bb9fccee2d669aec6a8c09ff92beaf8d 100644 (file)
@@ -9,7 +9,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
                       const struct nf_nat_range2 *range,
                       const struct net_device *out);
 
-void nf_nat_masquerade_ipv4_register_notifier(void);
+int nf_nat_masquerade_ipv4_register_notifier(void);
 void nf_nat_masquerade_ipv4_unregister_notifier(void);
 
 #endif /*_NF_NAT_MASQUERADE_IPV4_H_ */
index 0c3b5ebf0bb8d4832322ed16c1c3a106712d73d3..2917bf95c4370db57fcc64a6bb76fd64ad1ef902 100644 (file)
@@ -5,7 +5,7 @@
 unsigned int
 nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
                       const struct net_device *out);