]> git.codelabs.ch Git - muen/linux.git/commitdiff
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 26 May 2018 20:10:16 +0000 (13:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 26 May 2018 20:10:16 +0000 (13:10 -0700)
Pull scheduler fixes from Thomas Gleixner:
 "Three fixes for scheduler and kthread code:

   - allow calling kthread_park() on an already parked thread

   - restore the sched_pi_setprio() tracepoint behaviour

   - clarify the unclear string for the scheduling domain debug output"

* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  sched, tracing: Fix trace_sched_pi_setprio() for deboosting
  kthread: Allow kthread_park() on a parked kthread
  sched/topology: Clarify root domain(s) debug string

92 files changed:
Documentation/networking/ppp_generic.txt
MAINTAINERS
arch/arm64/include/asm/atomic_lse.h
arch/arm64/kernel/arm64ksyms.c
arch/arm64/lib/tishift.S
arch/arm64/mm/fault.c
arch/arm64/mm/mmu.c
arch/powerpc/include/asm/kvm_book3s.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cpu_setup_power.S
arch/powerpc/kernel/dt_cpu_ftrs.c
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_xive_template.c
arch/s390/kvm/vsie.c
arch/x86/kvm/cpuid.c
arch/x86/kvm/hyperv.c
arch/x86/kvm/lapic.c
arch/x86/kvm/x86.c
drivers/base/node.c
drivers/bcma/driver_mips.c
drivers/gpu/drm/rcar-du/rcar_lvds.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.h
drivers/isdn/hardware/eicon/diva.c
drivers/isdn/hardware/eicon/diva.h
drivers/isdn/hardware/eicon/divasmain.c
drivers/mmc/core/block.c
drivers/mmc/host/sdhci-iproc.c
drivers/net/ethernet/amd/pcnet32.c
drivers/net/ethernet/cisco/enic/enic_main.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/mellanox/mlx4/icm.c
drivers/net/ethernet/mellanox/mlx4/intf.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/qlogic/qed/qed_cxt.c
drivers/net/phy/bcm-cygnus.c
drivers/net/phy/bcm-phy-lib.c
drivers/net/phy/bcm-phy-lib.h
drivers/net/phy/bcm7xxx.c
drivers/net/ppp/ppp_generic.c
drivers/net/tun.c
drivers/net/virtio_net.c
drivers/net/wireless/mac80211_hwsim.c
drivers/ssb/Kconfig
drivers/vhost/vhost.c
fs/ocfs2/cluster/heartbeat.c
fs/seq_file.c
include/linux/bpf_verifier.h
include/linux/gfp.h
include/linux/node.h
include/net/sctp/sctp.h
include/uapi/linux/nl80211.h
include/uapi/linux/ppp-ioctl.h
init/main.c
ipc/shm.c
kernel/bpf/verifier.c
kernel/sys.c
lib/radix-tree.c
mm/kasan/kasan.c
mm/memory_hotplug.c
mm/page_alloc.c
mm/swapfile.c
net/batman-adv/multicast.c
net/batman-adv/translation-table.c
net/dccp/proto.c
net/ipv4/fib_frontend.c
net/ipv4/ip_sockglue.c
net/ipv4/ipmr_base.c
net/mac80211/mesh_plink.c
net/packet/af_packet.c
net/sched/cls_api.c
net/sctp/ipv6.c
net/sctp/protocol.c
net/sctp/socket.c
net/wireless/nl80211.c
net/wireless/reg.c
scripts/checkpatch.pl
sound/core/timer.c
sound/pci/hda/hda_local.h
tools/testing/radix-tree/idr-test.c
tools/testing/selftests/bpf/config
tools/testing/selftests/net/config
tools/testing/selftests/net/reuseport_bpf_numa.c

index 091d20273dcbbce70c75d1c1de76af25e100e344..61daf4b39600917a3baec3d9e200047f0831493a 100644 (file)
@@ -300,12 +300,6 @@ unattached instance are:
 The ioctl calls available on an instance of /dev/ppp attached to a
 channel are:
 
-* PPPIOCDETACH detaches the instance from the channel.  This ioctl is
-  deprecated since the same effect can be achieved by closing the
-  instance.  In order to prevent possible races this ioctl will fail
-  with an EINVAL error if more than one file descriptor refers to this
-  instance (i.e. as a result of dup(), dup2() or fork()).
-
 * PPPIOCCONNECT connects this channel to a PPP interface.  The
   argument should point to an int containing the interface unit
   number.  It will return an EINVAL error if the channel is already
index a9ca122957e977bd80e24f2bd2ca71839066542e..ca4afd68530ca7e83f403b9bb1f5025f6579cd01 100644 (file)
@@ -2332,7 +2332,7 @@ F:        drivers/gpio/gpio-ath79.c
 F:     Documentation/devicetree/bindings/gpio/gpio-ath79.txt
 
 ATHEROS ATH GENERIC UTILITIES
-M:     "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
+M:     Kalle Valo <kvalo@codeaurora.org>
 L:     linux-wireless@vger.kernel.org
 S:     Supported
 F:     drivers/net/wireless/ath/*
@@ -2347,7 +2347,7 @@ S:        Maintained
 F:     drivers/net/wireless/ath/ath5k/
 
 ATHEROS ATH6KL WIRELESS DRIVER
-M:     Kalle Valo <kvalo@qca.qualcomm.com>
+M:     Kalle Valo <kvalo@codeaurora.org>
 L:     linux-wireless@vger.kernel.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath6kl
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
@@ -6503,9 +6503,15 @@ F:       Documentation/networking/hinic.txt
 F:     drivers/net/ethernet/huawei/hinic/
 
 HUGETLB FILESYSTEM
-M:     Nadia Yvette Chambers <nyc@holomorphy.com>
+M:     Mike Kravetz <mike.kravetz@oracle.com>
+L:     linux-mm@kvack.org
 S:     Maintained
 F:     fs/hugetlbfs/
+F:     mm/hugetlb.c
+F:     include/linux/hugetlb.h
+F:     Documentation/admin-guide/mm/hugetlbpage.rst
+F:     Documentation/vm/hugetlbfs_reserv.rst
+F:     Documentation/ABI/testing/sysfs-kernel-mm-hugepages
 
 HVA ST MEDIA DRIVER
 M:     Jean-Christophe Trotin <jean-christophe.trotin@st.com>
@@ -11626,7 +11632,7 @@ S:      Maintained
 F:     drivers/media/tuners/qt1010*
 
 QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
-M:     Kalle Valo <kvalo@qca.qualcomm.com>
+M:     Kalle Valo <kvalo@codeaurora.org>
 L:     ath10k@lists.infradead.org
 W:     http://wireless.kernel.org/en/users/Drivers/ath10k
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
@@ -11677,7 +11683,7 @@ S:      Maintained
 F:     drivers/media/platform/qcom/venus/
 
 QUALCOMM WCN36XX WIRELESS DRIVER
-M:     Eugene Krasnikov <k.eugene.e@gmail.com>
+M:     Kalle Valo <kvalo@codeaurora.org>
 L:     wcn36xx@lists.infradead.org
 W:     http://wireless.kernel.org/en/users/Drivers/wcn36xx
 T:     git git://github.com/KrasnikovEugene/wcn36xx.git
index 9ef0797380cbbdf182a86e934c2eec5aa97d889d..f9b0b09153e0eaa3b15728fd42471c77c2d1955a 100644 (file)
@@ -117,7 +117,7 @@ static inline void atomic_and(int i, atomic_t *v)
        /* LSE atomics */
        "       mvn     %w[i], %w[i]\n"
        "       stclr   %w[i], %[v]")
-       : [i] "+r" (w0), [v] "+Q" (v->counter)
+       : [i] "+&r" (w0), [v] "+Q" (v->counter)
        : "r" (x1)
        : __LL_SC_CLOBBERS);
 }
@@ -135,7 +135,7 @@ static inline int atomic_fetch_and##name(int i, atomic_t *v)                \
        /* LSE atomics */                                               \
        "       mvn     %w[i], %w[i]\n"                                 \
        "       ldclr" #mb "    %w[i], %w[i], %[v]")                    \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS, ##cl);                                      \
                                                                        \
@@ -161,7 +161,7 @@ static inline void atomic_sub(int i, atomic_t *v)
        /* LSE atomics */
        "       neg     %w[i], %w[i]\n"
        "       stadd   %w[i], %[v]")
-       : [i] "+r" (w0), [v] "+Q" (v->counter)
+       : [i] "+&r" (w0), [v] "+Q" (v->counter)
        : "r" (x1)
        : __LL_SC_CLOBBERS);
 }
@@ -180,7 +180,7 @@ static inline int atomic_sub_return##name(int i, atomic_t *v)               \
        "       neg     %w[i], %w[i]\n"                                 \
        "       ldadd" #mb "    %w[i], w30, %[v]\n"                     \
        "       add     %w[i], %w[i], w30")                             \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS , ##cl);                                     \
                                                                        \
@@ -207,7 +207,7 @@ static inline int atomic_fetch_sub##name(int i, atomic_t *v)                \
        /* LSE atomics */                                               \
        "       neg     %w[i], %w[i]\n"                                 \
        "       ldadd" #mb "    %w[i], %w[i], %[v]")                    \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS, ##cl);                                      \
                                                                        \
@@ -314,7 +314,7 @@ static inline void atomic64_and(long i, atomic64_t *v)
        /* LSE atomics */
        "       mvn     %[i], %[i]\n"
        "       stclr   %[i], %[v]")
-       : [i] "+r" (x0), [v] "+Q" (v->counter)
+       : [i] "+&r" (x0), [v] "+Q" (v->counter)
        : "r" (x1)
        : __LL_SC_CLOBBERS);
 }
@@ -332,7 +332,7 @@ static inline long atomic64_fetch_and##name(long i, atomic64_t *v)  \
        /* LSE atomics */                                               \
        "       mvn     %[i], %[i]\n"                                   \
        "       ldclr" #mb "    %[i], %[i], %[v]")                      \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS, ##cl);                                      \
                                                                        \
@@ -358,7 +358,7 @@ static inline void atomic64_sub(long i, atomic64_t *v)
        /* LSE atomics */
        "       neg     %[i], %[i]\n"
        "       stadd   %[i], %[v]")
-       : [i] "+r" (x0), [v] "+Q" (v->counter)
+       : [i] "+&r" (x0), [v] "+Q" (v->counter)
        : "r" (x1)
        : __LL_SC_CLOBBERS);
 }
@@ -377,7 +377,7 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \
        "       neg     %[i], %[i]\n"                                   \
        "       ldadd" #mb "    %[i], x30, %[v]\n"                      \
        "       add     %[i], %[i], x30")                               \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS, ##cl);                                      \
                                                                        \
@@ -404,7 +404,7 @@ static inline long atomic64_fetch_sub##name(long i, atomic64_t *v)  \
        /* LSE atomics */                                               \
        "       neg     %[i], %[i]\n"                                   \
        "       ldadd" #mb "    %[i], %[i], %[v]")                      \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
+       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
        : "r" (x1)                                                      \
        : __LL_SC_CLOBBERS, ##cl);                                      \
                                                                        \
@@ -435,7 +435,7 @@ static inline long atomic64_dec_if_positive(atomic64_t *v)
        "       sub     x30, x30, %[ret]\n"
        "       cbnz    x30, 1b\n"
        "2:")
-       : [ret] "+r" (x0), [v] "+Q" (v->counter)
+       : [ret] "+&r" (x0), [v] "+Q" (v->counter)
        :
        : __LL_SC_CLOBBERS, "cc", "memory");
 
@@ -516,7 +516,7 @@ static inline long __cmpxchg_double##name(unsigned long old1,               \
        "       eor     %[old1], %[old1], %[oldval1]\n"                 \
        "       eor     %[old2], %[old2], %[oldval2]\n"                 \
        "       orr     %[old1], %[old1], %[old2]")                     \
-       : [old1] "+r" (x0), [old2] "+r" (x1),                           \
+       : [old1] "+&r" (x0), [old2] "+&r" (x1),                         \
          [v] "+Q" (*(unsigned long *)ptr)                              \
        : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),             \
          [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)              \
index 66be504edb6cf5be422afa59d82aa2db4fd3ed7f..d894a20b70b28f709f776d0330edb598283aecad 100644 (file)
@@ -75,3 +75,11 @@ NOKPROBE_SYMBOL(_mcount);
        /* arm-smccc */
 EXPORT_SYMBOL(__arm_smccc_smc);
 EXPORT_SYMBOL(__arm_smccc_hvc);
+
+       /* tishift.S */
+extern long long __ashlti3(long long a, int b);
+EXPORT_SYMBOL(__ashlti3);
+extern long long __ashrti3(long long a, int b);
+EXPORT_SYMBOL(__ashrti3);
+extern long long __lshrti3(long long a, int b);
+EXPORT_SYMBOL(__lshrti3);
index d3db9b2cd479bebb64e0dd0b3c18edfef3d552b0..0fdff97794debbdfaae4a146a99b4550e670ab5e 100644 (file)
@@ -1,17 +1,6 @@
-/*
- * Copyright (C) 2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * Copyright (C) 2017-2018 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  */
 
 #include <linux/linkage.h>
index 4165485e8b6ecbc60f161d98c20139992877c416..2af3dd89bcdbed669238b10defa7fc7deb1e2640 100644 (file)
@@ -293,6 +293,57 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr,
 static void __do_user_fault(struct siginfo *info, unsigned int esr)
 {
        current->thread.fault_address = (unsigned long)info->si_addr;
+
+       /*
+        * If the faulting address is in the kernel, we must sanitize the ESR.
+        * From userspace's point of view, kernel-only mappings don't exist
+        * at all, so we report them as level 0 translation faults.
+        * (This is not quite the way that "no mapping there at all" behaves:
+        * an alignment fault not caused by the memory type would take
+        * precedence over translation fault for a real access to empty
+        * space. Unfortunately we can't easily distinguish "alignment fault
+        * not caused by memory type" from "alignment fault caused by memory
+        * type", so we ignore this wrinkle and just return the translation
+        * fault.)
+        */
+       if (current->thread.fault_address >= TASK_SIZE) {
+               switch (ESR_ELx_EC(esr)) {
+               case ESR_ELx_EC_DABT_LOW:
+                       /*
+                        * These bits provide only information about the
+                        * faulting instruction, which userspace knows already.
+                        * We explicitly clear bits which are architecturally
+                        * RES0 in case they are given meanings in future.
+                        * We always report the ESR as if the fault was taken
+                        * to EL1 and so ISV and the bits in ISS[23:14] are
+                        * clear. (In fact it always will be a fault to EL1.)
+                        */
+                       esr &= ESR_ELx_EC_MASK | ESR_ELx_IL |
+                               ESR_ELx_CM | ESR_ELx_WNR;
+                       esr |= ESR_ELx_FSC_FAULT;
+                       break;
+               case ESR_ELx_EC_IABT_LOW:
+                       /*
+                        * Claim a level 0 translation fault.
+                        * All other bits are architecturally RES0 for faults
+                        * reported with that DFSC value, so we clear them.
+                        */
+                       esr &= ESR_ELx_EC_MASK | ESR_ELx_IL;
+                       esr |= ESR_ELx_FSC_FAULT;
+                       break;
+               default:
+                       /*
+                        * This should never happen (entry.S only brings us
+                        * into this code for insn and data aborts from a lower
+                        * exception level). Fail safe by not providing an ESR
+                        * context record at all.
+                        */
+                       WARN(1, "ESR 0x%x is not DABT or IABT from EL0\n", esr);
+                       esr = 0;
+                       break;
+               }
+       }
+
        current->thread.fault_code = esr;
        arm64_force_sig_info(info, esr_to_fault_info(esr)->name, current);
 }
index 2dbb2c9f1ec1770e7f9f5aca7176eac2cc153d32..493ff75670ffd98a1dc344a133f0f31a634f93ff 100644 (file)
@@ -933,13 +933,15 @@ int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
 {
        pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
                                        pgprot_val(mk_sect_prot(prot)));
+       pud_t new_pud = pfn_pud(__phys_to_pfn(phys), sect_prot);
 
-       /* ioremap_page_range doesn't honour BBM */
-       if (pud_present(READ_ONCE(*pudp)))
+       /* Only allow permission changes for now */
+       if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pudp)),
+                                  pud_val(new_pud)))
                return 0;
 
        BUG_ON(phys & ~PUD_MASK);
-       set_pud(pudp, pfn_pud(__phys_to_pfn(phys), sect_prot));
+       set_pud(pudp, new_pud);
        return 1;
 }
 
@@ -947,13 +949,15 @@ int pmd_set_huge(pmd_t *pmdp, phys_addr_t phys, pgprot_t prot)
 {
        pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
                                        pgprot_val(mk_sect_prot(prot)));
+       pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), sect_prot);
 
-       /* ioremap_page_range doesn't honour BBM */
-       if (pmd_present(READ_ONCE(*pmdp)))
+       /* Only allow permission changes for now */
+       if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmdp)),
+                                  pmd_val(new_pmd)))
                return 0;
 
        BUG_ON(phys & ~PMD_MASK);
-       set_pmd(pmdp, pfn_pmd(__phys_to_pfn(phys), sect_prot));
+       set_pmd(pmdp, new_pmd);
        return 1;
 }
 
index 4c02a7378d067e6dd5afc12b7336f90353879abc..e7377b73cfecaa2874fe240ee861e472cfa9309d 100644 (file)
@@ -96,6 +96,7 @@ struct kvmppc_vcore {
        struct kvm_vcpu *runner;
        struct kvm *kvm;
        u64 tb_offset;          /* guest timebase - host timebase */
+       u64 tb_offset_applied;  /* timebase offset currently in force */
        ulong lpcr;
        u32 arch_compat;
        ulong pcr;
index 6bee65f3cfd34bf896ef770f805ec62d417ae9db..373dc1d6ef44e99854200208466f741489944423 100644 (file)
@@ -562,6 +562,7 @@ int main(void)
        OFFSET(VCORE_NAPPING_THREADS, kvmppc_vcore, napping_threads);
        OFFSET(VCORE_KVM, kvmppc_vcore, kvm);
        OFFSET(VCORE_TB_OFFSET, kvmppc_vcore, tb_offset);
+       OFFSET(VCORE_TB_OFFSET_APPL, kvmppc_vcore, tb_offset_applied);
        OFFSET(VCORE_LPCR, kvmppc_vcore, lpcr);
        OFFSET(VCORE_PCR, kvmppc_vcore, pcr);
        OFFSET(VCORE_DPDES, kvmppc_vcore, dpdes);
index 3f30c994e9316a1476086334de4fa84edba9de0e..458b928dbd8447008a7f6c83ff9db27d06d7508d 100644 (file)
@@ -28,6 +28,7 @@ _GLOBAL(__setup_cpu_power7)
        beqlr
        li      r0,0
        mtspr   SPRN_LPID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        li      r4,(LPCR_LPES1 >> LPCR_LPES_SH)
        bl      __init_LPCR_ISA206
@@ -41,6 +42,7 @@ _GLOBAL(__restore_cpu_power7)
        beqlr
        li      r0,0
        mtspr   SPRN_LPID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        li      r4,(LPCR_LPES1 >> LPCR_LPES_SH)
        bl      __init_LPCR_ISA206
@@ -57,6 +59,7 @@ _GLOBAL(__setup_cpu_power8)
        beqlr
        li      r0,0
        mtspr   SPRN_LPID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        ori     r3, r3, LPCR_PECEDH
        li      r4,0 /* LPES = 0 */
@@ -78,6 +81,7 @@ _GLOBAL(__restore_cpu_power8)
        beqlr
        li      r0,0
        mtspr   SPRN_LPID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        ori     r3, r3, LPCR_PECEDH
        li      r4,0 /* LPES = 0 */
@@ -99,6 +103,7 @@ _GLOBAL(__setup_cpu_power9)
        mtspr   SPRN_PSSCR,r0
        mtspr   SPRN_LPID,r0
        mtspr   SPRN_PID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE  | LPCR_HEIC)
        or      r3, r3, r4
@@ -123,6 +128,7 @@ _GLOBAL(__restore_cpu_power9)
        mtspr   SPRN_PSSCR,r0
        mtspr   SPRN_LPID,r0
        mtspr   SPRN_PID,r0
+       mtspr   SPRN_PCR,r0
        mfspr   r3,SPRN_LPCR
        LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC)
        or      r3, r3, r4
index 8ab51f6ca03af52c4d9cff18e552b456022e459e..c904477abaf38d33c63ee5d0822714f1d36f9b85 100644 (file)
@@ -101,6 +101,7 @@ static void __restore_cpu_cpufeatures(void)
        if (hv_mode) {
                mtspr(SPRN_LPID, 0);
                mtspr(SPRN_HFSCR, system_registers.hfscr);
+               mtspr(SPRN_PCR, 0);
        }
        mtspr(SPRN_FSCR, system_registers.fscr);
 
index a57eafec4dc2eedb779182e5a12dd1bd6c0bbcd9..361f42c8c73e02f95a4617b967174f37b774504c 100644 (file)
@@ -162,7 +162,7 @@ static void kvmppc_radix_tlbie_page(struct kvm *kvm, unsigned long addr,
        if (cpu_has_feature(CPU_FTR_P9_TLBIE_BUG))
                asm volatile(PPC_TLBIE_5(%0, %1, 0, 0, 1)
                             : : "r" (addr), "r" (kvm->arch.lpid) : "memory");
-       asm volatile("ptesync": : :"memory");
+       asm volatile("eieio ; tlbsync ; ptesync": : :"memory");
 }
 
 static void kvmppc_radix_flush_pwc(struct kvm *kvm, unsigned long addr)
@@ -173,7 +173,7 @@ static void kvmppc_radix_flush_pwc(struct kvm *kvm, unsigned long addr)
        /* RIC=1 PRS=0 R=1 IS=2 */
        asm volatile(PPC_TLBIE_5(%0, %1, 1, 0, 1)
                     : : "r" (rb), "r" (kvm->arch.lpid) : "memory");
-       asm volatile("ptesync": : :"memory");
+       asm volatile("eieio ; tlbsync ; ptesync": : :"memory");
 }
 
 unsigned long kvmppc_radix_update_pte(struct kvm *kvm, pte_t *ptep,
@@ -584,7 +584,7 @@ int kvm_unmap_radix(struct kvm *kvm, struct kvm_memory_slot *memslot,
 
        ptep = __find_linux_pte(kvm->arch.pgtable, gpa, NULL, &shift);
        if (ptep && pte_present(*ptep)) {
-               old = kvmppc_radix_update_pte(kvm, ptep, _PAGE_PRESENT, 0,
+               old = kvmppc_radix_update_pte(kvm, ptep, ~0UL, 0,
                                              gpa, shift);
                kvmppc_radix_tlbie_page(kvm, gpa, shift);
                if ((old & _PAGE_DIRTY) && memslot->dirty_bitmap) {
index 4d07fca5121c56270aafd6f820009561d399d628..9963f65c212b8cad5a348830651df52b2b7e0c0f 100644 (file)
@@ -2441,6 +2441,7 @@ static void init_vcore_to_run(struct kvmppc_vcore *vc)
        vc->in_guest = 0;
        vc->napping_threads = 0;
        vc->conferring_threads = 0;
+       vc->tb_offset_applied = 0;
 }
 
 static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip)
index bd63fa8a08b5dd3edd0800ac34e483a8501f401c..07ca1b2a7966b5f58188b8b0b685eb581cc2b695 100644 (file)
@@ -692,6 +692,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 22:    ld      r8,VCORE_TB_OFFSET(r5)
        cmpdi   r8,0
        beq     37f
+       std     r8, VCORE_TB_OFFSET_APPL(r5)
        mftb    r6              /* current host timebase */
        add     r8,r8,r6
        mtspr   SPRN_TBU40,r8   /* update upper 40 bits */
@@ -940,18 +941,6 @@ FTR_SECTION_ELSE
 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
 8:
 
-       /*
-        * Set the decrementer to the guest decrementer.
-        */
-       ld      r8,VCPU_DEC_EXPIRES(r4)
-       /* r8 is a host timebase value here, convert to guest TB */
-       ld      r5,HSTATE_KVM_VCORE(r13)
-       ld      r6,VCORE_TB_OFFSET(r5)
-       add     r8,r8,r6
-       mftb    r7
-       subf    r3,r7,r8
-       mtspr   SPRN_DEC,r3
-
        ld      r5, VCPU_SPRG0(r4)
        ld      r6, VCPU_SPRG1(r4)
        ld      r7, VCPU_SPRG2(r4)
@@ -1005,6 +994,18 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
        mtspr   SPRN_LPCR,r8
        isync
 
+       /*
+        * Set the decrementer to the guest decrementer.
+        */
+       ld      r8,VCPU_DEC_EXPIRES(r4)
+       /* r8 is a host timebase value here, convert to guest TB */
+       ld      r5,HSTATE_KVM_VCORE(r13)
+       ld      r6,VCORE_TB_OFFSET_APPL(r5)
+       add     r8,r8,r6
+       mftb    r7
+       subf    r3,r7,r8
+       mtspr   SPRN_DEC,r3
+
        /* Check if HDEC expires soon */
        mfspr   r3, SPRN_HDEC
        EXTEND_HDEC(r3)
@@ -1597,8 +1598,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
 
 guest_bypass:
        stw     r12, STACK_SLOT_TRAP(r1)
-       mr      r3, r12
+
+       /* Save DEC */
+       /* Do this before kvmhv_commence_exit so we know TB is guest TB */
+       ld      r3, HSTATE_KVM_VCORE(r13)
+       mfspr   r5,SPRN_DEC
+       mftb    r6
+       /* On P9, if the guest has large decr enabled, don't sign extend */
+BEGIN_FTR_SECTION
+       ld      r4, VCORE_LPCR(r3)
+       andis.  r4, r4, LPCR_LD@h
+       bne     16f
+END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
+       extsw   r5,r5
+16:    add     r5,r5,r6
+       /* r5 is a guest timebase value here, convert to host TB */
+       ld      r4,VCORE_TB_OFFSET_APPL(r3)
+       subf    r5,r4,r5
+       std     r5,VCPU_DEC_EXPIRES(r9)
+
        /* Increment exit count, poke other threads to exit */
+       mr      r3, r12
        bl      kvmhv_commence_exit
        nop
        ld      r9, HSTATE_KVM_VCPU(r13)
@@ -1639,23 +1659,6 @@ guest_bypass:
        mtspr   SPRN_PURR,r3
        mtspr   SPRN_SPURR,r4
 
-       /* Save DEC */
-       ld      r3, HSTATE_KVM_VCORE(r13)
-       mfspr   r5,SPRN_DEC
-       mftb    r6
-       /* On P9, if the guest has large decr enabled, don't sign extend */
-BEGIN_FTR_SECTION
-       ld      r4, VCORE_LPCR(r3)
-       andis.  r4, r4, LPCR_LD@h
-       bne     16f
-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
-       extsw   r5,r5
-16:    add     r5,r5,r6
-       /* r5 is a guest timebase value here, convert to host TB */
-       ld      r4,VCORE_TB_OFFSET(r3)
-       subf    r5,r4,r5
-       std     r5,VCPU_DEC_EXPIRES(r9)
-
 BEGIN_FTR_SECTION
        b       8f
 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
@@ -1905,6 +1908,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        cmpwi   cr2, r0, 0
        beq     cr2, 4f
 
+       /*
+        * Radix: do eieio; tlbsync; ptesync sequence in case we
+        * interrupted the guest between a tlbie and a ptesync.
+        */
+       eieio
+       tlbsync
+       ptesync
+
        /* Radix: Handle the case where the guest used an illegal PID */
        LOAD_REG_ADDR(r4, mmu_base_pid)
        lwz     r3, VCPU_GUEST_PID(r9)
@@ -2017,9 +2028,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 
 27:
        /* Subtract timebase offset from timebase */
-       ld      r8,VCORE_TB_OFFSET(r5)
+       ld      r8, VCORE_TB_OFFSET_APPL(r5)
        cmpdi   r8,0
        beq     17f
+       li      r0, 0
+       std     r0, VCORE_TB_OFFSET_APPL(r5)
        mftb    r6                      /* current guest timebase */
        subf    r8,r8,r6
        mtspr   SPRN_TBU40,r8           /* update upper 40 bits */
@@ -2700,7 +2713,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        add     r3, r3, r5
        ld      r4, HSTATE_KVM_VCPU(r13)
        ld      r5, HSTATE_KVM_VCORE(r13)
-       ld      r6, VCORE_TB_OFFSET(r5)
+       ld      r6, VCORE_TB_OFFSET_APPL(r5)
        subf    r3, r6, r3      /* convert to host TB value */
        std     r3, VCPU_DEC_EXPIRES(r4)
 
@@ -2799,7 +2812,7 @@ END_FTR_SECTION(CPU_FTR_TM | CPU_FTR_P9_TM_HV_ASSIST, 0)
        /* Restore guest decrementer */
        ld      r3, VCPU_DEC_EXPIRES(r4)
        ld      r5, HSTATE_KVM_VCORE(r13)
-       ld      r6, VCORE_TB_OFFSET(r5)
+       ld      r6, VCORE_TB_OFFSET_APPL(r5)
        add     r3, r3, r6      /* convert host TB to guest TB value */
        mftb    r7
        subf    r3, r7, r3
@@ -3606,12 +3619,9 @@ kvmppc_fix_pmao:
  */
 kvmhv_start_timing:
        ld      r5, HSTATE_KVM_VCORE(r13)
-       lbz     r6, VCORE_IN_GUEST(r5)
-       cmpwi   r6, 0
-       beq     5f                              /* if in guest, need to */
-       ld      r6, VCORE_TB_OFFSET(r5)         /* subtract timebase offset */
-5:     mftb    r5
-       subf    r5, r6, r5
+       ld      r6, VCORE_TB_OFFSET_APPL(r5)
+       mftb    r5
+       subf    r5, r6, r5      /* subtract current timebase offset */
        std     r3, VCPU_CUR_ACTIVITY(r4)
        std     r5, VCPU_ACTIVITY_START(r4)
        blr
@@ -3622,15 +3632,12 @@ kvmhv_start_timing:
  */
 kvmhv_accumulate_time:
        ld      r5, HSTATE_KVM_VCORE(r13)
-       lbz     r8, VCORE_IN_GUEST(r5)
-       cmpwi   r8, 0
-       beq     4f                              /* if in guest, need to */
-       ld      r8, VCORE_TB_OFFSET(r5)         /* subtract timebase offset */
-4:     ld      r5, VCPU_CUR_ACTIVITY(r4)
+       ld      r8, VCORE_TB_OFFSET_APPL(r5)
+       ld      r5, VCPU_CUR_ACTIVITY(r4)
        ld      r6, VCPU_ACTIVITY_START(r4)
        std     r3, VCPU_CUR_ACTIVITY(r4)
        mftb    r7
-       subf    r7, r8, r7
+       subf    r7, r8, r7      /* subtract current timebase offset */
        std     r7, VCPU_ACTIVITY_START(r4)
        cmpdi   r5, 0
        beqlr
index c7a5deadd1cc782ddd45667c9fc29f96166e85e7..99c3620b40d95b91481a5485ab6e2649ea40c37c 100644 (file)
@@ -11,6 +11,9 @@
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
 
+/* Dummy interrupt used when taking interrupts out of a queue in H_CPPR */
+#define XICS_DUMMY     1
+
 static void GLUE(X_PFX,ack_pending)(struct kvmppc_xive_vcpu *xc)
 {
        u8 cppr;
@@ -205,6 +208,10 @@ skip_ipi:
                                goto skip_ipi;
                }
 
+               /* If it's the dummy interrupt, continue searching */
+               if (hirq == XICS_DUMMY)
+                       goto skip_ipi;
+
                /* If fetching, update queue pointers */
                if (scan_type == scan_fetch) {
                        q->idx = idx;
@@ -385,9 +392,76 @@ static void GLUE(X_PFX,push_pending_to_hw)(struct kvmppc_xive_vcpu *xc)
        __x_writeb(prio, __x_tima + TM_SPC_SET_OS_PENDING);
 }
 
+static void GLUE(X_PFX,scan_for_rerouted_irqs)(struct kvmppc_xive *xive,
+                                              struct kvmppc_xive_vcpu *xc)
+{
+       unsigned int prio;
+
+       /* For each priority that is now masked */
+       for (prio = xc->cppr; prio < KVMPPC_XIVE_Q_COUNT; prio++) {
+               struct xive_q *q = &xc->queues[prio];
+               struct kvmppc_xive_irq_state *state;
+               struct kvmppc_xive_src_block *sb;
+               u32 idx, toggle, entry, irq, hw_num;
+               struct xive_irq_data *xd;
+               __be32 *qpage;
+               u16 src;
+
+               idx = q->idx;
+               toggle = q->toggle;
+               qpage = READ_ONCE(q->qpage);
+               if (!qpage)
+                       continue;
+
+               /* For each interrupt in the queue */
+               for (;;) {
+                       entry = be32_to_cpup(qpage + idx);
+
+                       /* No more ? */
+                       if ((entry >> 31) == toggle)
+                               break;
+                       irq = entry & 0x7fffffff;
+
+                       /* Skip dummies and IPIs */
+                       if (irq == XICS_DUMMY || irq == XICS_IPI)
+                               goto next;
+                       sb = kvmppc_xive_find_source(xive, irq, &src);
+                       if (!sb)
+                               goto next;
+                       state = &sb->irq_state[src];
+
+                       /* Has it been rerouted ? */
+                       if (xc->server_num == state->act_server)
+                               goto next;
+
+                       /*
+                        * Allright, it *has* been re-routed, kill it from
+                        * the queue.
+                        */
+                       qpage[idx] = cpu_to_be32((entry & 0x80000000) | XICS_DUMMY);
+
+                       /* Find the HW interrupt */
+                       kvmppc_xive_select_irq(state, &hw_num, &xd);
+
+                       /* If it's not an LSI, set PQ to 11 the EOI will force a resend */
+                       if (!(xd->flags & XIVE_IRQ_FLAG_LSI))
+                               GLUE(X_PFX,esb_load)(xd, XIVE_ESB_SET_PQ_11);
+
+                       /* EOI the source */
+                       GLUE(X_PFX,source_eoi)(hw_num, xd);
+
+               next:
+                       idx = (idx + 1) & q->msk;
+                       if (idx == 0)
+                               toggle ^= 1;
+               }
+       }
+}
+
 X_STATIC int GLUE(X_PFX,h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr)
 {
        struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
+       struct kvmppc_xive *xive = vcpu->kvm->arch.xive;
        u8 old_cppr;
 
        pr_devel("H_CPPR(cppr=%ld)\n", cppr);
@@ -407,14 +481,34 @@ X_STATIC int GLUE(X_PFX,h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr)
         */
        smp_mb();
 
-       /*
-        * We are masking less, we need to look for pending things
-        * to deliver and set VP pending bits accordingly to trigger
-        * a new interrupt otherwise we might miss MFRR changes for
-        * which we have optimized out sending an IPI signal.
-        */
-       if (cppr > old_cppr)
+       if (cppr > old_cppr) {
+               /*
+                * We are masking less, we need to look for pending things
+                * to deliver and set VP pending bits accordingly to trigger
+                * a new interrupt otherwise we might miss MFRR changes for
+                * which we have optimized out sending an IPI signal.
+                */
                GLUE(X_PFX,push_pending_to_hw)(xc);
+       } else {
+               /*
+                * We are masking more, we need to check the queue for any
+                * interrupt that has been routed to another CPU, take
+                * it out (replace it with the dummy) and retrigger it.
+                *
+                * This is necessary since those interrupts may otherwise
+                * never be processed, at least not until this CPU restores
+                * its CPPR.
+                *
+                * This is in theory racy vs. HW adding new interrupts to
+                * the queue. In practice this works because the interesting
+                * cases are when the guest has done a set_xive() to move the
+                * interrupt away, which flushes the xive, followed by the
+                * target CPU doing a H_CPPR. So any new interrupt coming into
+                * the queue must still be routed to us and isn't a source
+                * of concern.
+                */
+               GLUE(X_PFX,scan_for_rerouted_irqs)(xive, xc);
+       }
 
        /* Apply new CPPR */
        xc->hw_cppr = cppr;
index 8961e3970901d4b06c87b20f147115b683ad5170..969882b542669be1648093224c0ef802d027a161 100644 (file)
@@ -578,7 +578,7 @@ static int pin_blocks(struct kvm_vcpu *vcpu, struct vsie_page *vsie_page)
 
        gpa = READ_ONCE(scb_o->itdba) & ~0xffUL;
        if (gpa && (scb_s->ecb & ECB_TE)) {
-               if (!(gpa & ~0x1fffU)) {
+               if (!(gpa & ~0x1fffUL)) {
                        rc = set_validity_icpt(scb_s, 0x0080U);
                        goto unpin;
                }
index ced851169730a0cd3910d05baae61293d1f56a4f..9bffb5228f31670b790051c8aa329c2692c8ad92 100644 (file)
@@ -495,6 +495,11 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
                                entry->ecx &= ~F(PKU);
                        entry->edx &= kvm_cpuid_7_0_edx_x86_features;
                        cpuid_mask(&entry->edx, CPUID_7_EDX);
+                       /*
+                        * We emulate ARCH_CAPABILITIES in software even
+                        * if the host doesn't support it.
+                        */
+                       entry->edx |= F(ARCH_CAPABILITIES);
                } else {
                        entry->ebx = 0;
                        entry->ecx = 0;
index 5708e951a5c69664895a7b9a21ffe3c1bdc669bb..46ff64da44cab46d637facafffb10ba1a1269a1f 100644 (file)
@@ -1260,14 +1260,18 @@ static void kvm_hv_hypercall_set_result(struct kvm_vcpu *vcpu, u64 result)
        }
 }
 
-static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+static int kvm_hv_hypercall_complete(struct kvm_vcpu *vcpu, u64 result)
 {
-       struct kvm_run *run = vcpu->run;
-
-       kvm_hv_hypercall_set_result(vcpu, run->hyperv.u.hcall.result);
+       kvm_hv_hypercall_set_result(vcpu, result);
+       ++vcpu->stat.hypercalls;
        return kvm_skip_emulated_instruction(vcpu);
 }
 
+static int kvm_hv_hypercall_complete_userspace(struct kvm_vcpu *vcpu)
+{
+       return kvm_hv_hypercall_complete(vcpu, vcpu->run->hyperv.u.hcall.result);
+}
+
 static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, bool fast, u64 param)
 {
        struct eventfd_ctx *eventfd;
@@ -1350,7 +1354,7 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
        /* Hypercall continuation is not supported yet */
        if (rep_cnt || rep_idx) {
                ret = HV_STATUS_INVALID_HYPERCALL_CODE;
-               goto set_result;
+               goto out;
        }
 
        switch (code) {
@@ -1381,9 +1385,8 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu)
                break;
        }
 
-set_result:
-       kvm_hv_hypercall_set_result(vcpu, ret);
-       return 1;
+out:
+       return kvm_hv_hypercall_complete(vcpu, ret);
 }
 
 void kvm_hv_init_vm(struct kvm *kvm)
index b74c9c1405b9978331653daa9093e95c36be0252..3773c462511404bcc94ad69742b16fdfdc26a504 100644 (file)
@@ -1522,11 +1522,23 @@ static bool set_target_expiration(struct kvm_lapic *apic)
 
 static void advance_periodic_target_expiration(struct kvm_lapic *apic)
 {
-       apic->lapic_timer.tscdeadline +=
-               nsec_to_cycles(apic->vcpu, apic->lapic_timer.period);
+       ktime_t now = ktime_get();
+       u64 tscl = rdtsc();
+       ktime_t delta;
+
+       /*
+        * Synchronize both deadlines to the same time source or
+        * differences in the periods (caused by differences in the
+        * underlying clocks or numerical approximation errors) will
+        * cause the two to drift apart over time as the errors
+        * accumulate.
+        */
        apic->lapic_timer.target_expiration =
                ktime_add_ns(apic->lapic_timer.target_expiration,
                                apic->lapic_timer.period);
+       delta = ktime_sub(apic->lapic_timer.target_expiration, now);
+       apic->lapic_timer.tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) +
+               nsec_to_cycles(apic->vcpu, delta);
 }
 
 static void start_sw_period(struct kvm_lapic *apic)
index 22a183aac1c63f333efb446f1376d1ac09b85cd0..71e7cda6d01430bca8ef226238589ab0e830d6c9 100644 (file)
@@ -6671,11 +6671,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
        unsigned long nr, a0, a1, a2, a3, ret;
        int op_64_bit;
 
-       if (kvm_hv_hypercall_enabled(vcpu->kvm)) {
-               if (!kvm_hv_hypercall(vcpu))
-                       return 0;
-               goto out;
-       }
+       if (kvm_hv_hypercall_enabled(vcpu->kvm))
+               return kvm_hv_hypercall(vcpu);
 
        nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
        a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
@@ -6696,7 +6693,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 
        if (kvm_x86_ops->get_cpl(vcpu) != 0) {
                ret = -KVM_EPERM;
-               goto out_error;
+               goto out;
        }
 
        switch (nr) {
@@ -6716,12 +6713,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
                ret = -KVM_ENOSYS;
                break;
        }
-out_error:
+out:
        if (!op_64_bit)
                ret = (u32)ret;
        kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
 
-out:
        ++vcpu->stat.hypercalls;
        return kvm_skip_emulated_instruction(vcpu);
 }
@@ -7980,6 +7976,7 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
 {
        struct msr_data apic_base_msr;
        int mmu_reset_needed = 0;
+       int cpuid_update_needed = 0;
        int pending_vec, max_bits, idx;
        struct desc_ptr dt;
        int ret = -EINVAL;
@@ -8018,8 +8015,10 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
        vcpu->arch.cr0 = sregs->cr0;
 
        mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
+       cpuid_update_needed |= ((kvm_read_cr4(vcpu) ^ sregs->cr4) &
+                               (X86_CR4_OSXSAVE | X86_CR4_PKE));
        kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
-       if (sregs->cr4 & (X86_CR4_OSXSAVE | X86_CR4_PKE))
+       if (cpuid_update_needed)
                kvm_update_cpuid(vcpu);
 
        idx = srcu_read_lock(&vcpu->kvm->srcu);
index 7a3a580821e076741228473138cdae171fbbfaac..a5e821d09656bfae5df645988001ebec48fe0e3e 100644 (file)
@@ -490,7 +490,8 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
        return 0;
 }
 
-int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
+int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages,
+                     bool check_nid)
 {
        unsigned long end_pfn = start_pfn + nr_pages;
        unsigned long pfn;
@@ -514,7 +515,7 @@ int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
 
                mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
 
-               ret = register_mem_sect_under_node(mem_blk, nid, true);
+               ret = register_mem_sect_under_node(mem_blk, nid, check_nid);
                if (!err)
                        err = ret;
 
index f040aba48d5056c6e735ec4851a82f712dfdfa2c..27e9686b6d3a3bb499da4e724ce05d344ab24e86 100644 (file)
@@ -184,7 +184,7 @@ static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
 {
        int i;
        static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
-       char interrupts[20];
+       char interrupts[25];
        char *ints = interrupts;
 
        for (i = 0; i < ARRAY_SIZE(irq_name); i++)
index 3d2d3bbd1342052b2ddedcc0e95d0b4b84e6880c..155ad840f3c59d6cfae28caaba6a863ceb3880a9 100644 (file)
@@ -88,6 +88,9 @@ static int rcar_lvds_connector_atomic_check(struct drm_connector *connector,
        const struct drm_display_mode *panel_mode;
        struct drm_crtc_state *crtc_state;
 
+       if (!state->crtc)
+               return 0;
+
        if (list_empty(&connector->modes)) {
                dev_dbg(lvds->dev, "connector: empty modes list\n");
                return -EINVAL;
index 70e1a8820a7c01644cc1f5016d0a878b88c9dc23..8b770a8e02cdda09caee81be15ebc27434b4b67e 100644 (file)
@@ -1278,8 +1278,6 @@ static void vmw_master_drop(struct drm_device *dev,
        dev_priv->active_master = &dev_priv->fbdev_master;
        ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
        ttm_vt_unlock(&dev_priv->fbdev_master.lock);
-
-       vmw_fb_refresh(dev_priv);
 }
 
 /**
@@ -1483,7 +1481,6 @@ static int vmw_pm_freeze(struct device *kdev)
                        vmw_kms_resume(dev);
                if (dev_priv->enable_fb)
                        vmw_fb_on(dev_priv);
-               vmw_fb_refresh(dev_priv);
                return -EBUSY;
        }
 
@@ -1523,8 +1520,6 @@ static int vmw_pm_restore(struct device *kdev)
        if (dev_priv->enable_fb)
                vmw_fb_on(dev_priv);
 
-       vmw_fb_refresh(dev_priv);
-
        return 0;
 }
 
index f34f368c1a2ebc1713f35a7aab0f94c83061cbfa..5fcbe1620d50b34898815be80ec7560115c68997 100644 (file)
@@ -910,7 +910,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv);
 int vmw_fb_close(struct vmw_private *dev_priv);
 int vmw_fb_off(struct vmw_private *vmw_priv);
 int vmw_fb_on(struct vmw_private *vmw_priv);
-void vmw_fb_refresh(struct vmw_private *vmw_priv);
 
 /**
  * Kernel modesetting - vmwgfx_kms.c
index ba0cdb743c3e50d664848c021a0f63bc72953aa2..54e300365a5ccd04b2d5d6173fbb379bde860322 100644 (file)
@@ -866,21 +866,13 @@ int vmw_fb_on(struct vmw_private *vmw_priv)
        spin_lock_irqsave(&par->dirty.lock, flags);
        par->dirty.active = true;
        spin_unlock_irqrestore(&par->dirty.lock, flags);
-       return 0;
-}
 
-/**
- * vmw_fb_refresh - Refresh fb display
- *
- * @vmw_priv: Pointer to device private
- *
- * Call into kms to show the fbdev display(s).
- */
-void vmw_fb_refresh(struct vmw_private *vmw_priv)
-{
-       if (!vmw_priv->fb_info)
-               return;
+       /*
+        * Need to reschedule a dirty update, because otherwise that's
+        * only done in dirty_mark() if the previous coalesced
+        * dirty region was empty.
+        */
+       schedule_delayed_work(&par->local_work, 0);
 
-       vmw_fb_set_par(vmw_priv->fb_info);
+       return 0;
 }
index cdff99211602cc44901135f6dc0cdd781e849a21..21d746bdc922bc55ce27d25cd4d5c2ad935d595e 100644 (file)
@@ -329,8 +329,6 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
        struct rpc_channel channel;
        char *msg, *reply = NULL;
        size_t reply_len = 0;
-       int ret = 0;
-
 
        if (!vmw_msg_enabled)
                return -ENODEV;
@@ -344,15 +342,14 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
                return -ENOMEM;
        }
 
-       if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) ||
-           vmw_send_msg(&channel, msg) ||
-           vmw_recv_msg(&channel, (void *) &reply, &reply_len) ||
-           vmw_close_channel(&channel)) {
-               DRM_ERROR("Failed to get %s", guest_info_param);
+       if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM))
+               goto out_open;
 
-               ret = -EINVAL;
-       }
+       if (vmw_send_msg(&channel, msg) ||
+           vmw_recv_msg(&channel, (void *) &reply, &reply_len))
+               goto out_msg;
 
+       vmw_close_channel(&channel);
        if (buffer && reply && reply_len > 0) {
                /* Remove reply code, which are the first 2 characters of
                 * the reply
@@ -369,7 +366,17 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
        kfree(reply);
        kfree(msg);
 
-       return ret;
+       return 0;
+
+out_msg:
+       vmw_close_channel(&channel);
+       kfree(reply);
+out_open:
+       *length = 0;
+       kfree(msg);
+       DRM_ERROR("Failed to get %s", guest_info_param);
+
+       return -EINVAL;
 }
 
 
@@ -400,15 +407,22 @@ int vmw_host_log(const char *log)
                return -ENOMEM;
        }
 
-       if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) ||
-           vmw_send_msg(&channel, msg) ||
-           vmw_close_channel(&channel)) {
-               DRM_ERROR("Failed to send log\n");
+       if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM))
+               goto out_open;
 
-               ret = -EINVAL;
-       }
+       if (vmw_send_msg(&channel, msg))
+               goto out_msg;
 
+       vmw_close_channel(&channel);
        kfree(msg);
 
-       return ret;
+       return 0;
+
+out_msg:
+       vmw_close_channel(&channel);
+out_open:
+       kfree(msg);
+       DRM_ERROR("Failed to send log\n");
+
+       return -EINVAL;
 }
index 557a033fb610f1dfcb3568aceebd5592c97b3c60..8545488aa0cfbe1bf1b1d14514d6794c0077834a 100644 (file)
 
 #else
 
-/* In the 32-bit version of this macro, we use "m" because there is no
- * more register left for bp
+/*
+ * In the 32-bit version of this macro, we store bp in a memory location
+ * because we've ran out of registers.
+ * Now we can't reference that memory location while we've modified
+ * %esp or %ebp, so we first push it on the stack, just before we push
+ * %ebp, and then when we need it we read it from the stack where we
+ * just pushed it.
  */
 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,     \
                        port_num, magic, bp,            \
                        eax, ebx, ecx, edx, si, di)     \
 ({                                                     \
-       asm volatile ("push %%ebp;"                     \
-               "mov %12, %%ebp;"                       \
+       asm volatile ("push %12;"                       \
+               "push %%ebp;"                           \
+               "mov 0x04(%%esp), %%ebp;"               \
                "rep outsb;"                            \
-               "pop %%ebp;" :                          \
+               "pop %%ebp;"                            \
+               "add $0x04, %%esp;" :                   \
                "=a"(eax),                              \
                "=b"(ebx),                              \
                "=c"(ecx),                              \
                       port_num, magic, bp,             \
                       eax, ebx, ecx, edx, si, di)      \
 ({                                                     \
-       asm volatile ("push %%ebp;"                     \
-               "mov %12, %%ebp;"                       \
+       asm volatile ("push %12;"                       \
+               "push %%ebp;"                           \
+               "mov 0x04(%%esp), %%ebp;"               \
                "rep insb;"                             \
-               "pop %%ebp" :                           \
+               "pop %%ebp;"                            \
+               "add $0x04, %%esp;" :                   \
                "=a"(eax),                              \
                "=b"(ebx),                              \
                "=c"(ecx),                              \
index 944a7f3380991d107b0a3f50a9dfd100ba0719a8..1b25d8bc153aec16ea8e9ee0cd47de0604a2a393 100644 (file)
@@ -388,10 +388,10 @@ void divasa_xdi_driver_unload(void)
 **  Receive and process command from user mode utility
 */
 void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
-                           int length,
+                           int length, void *mptr,
                            divas_xdi_copy_from_user_fn_t cp_fn)
 {
-       diva_xdi_um_cfg_cmd_t msg;
+       diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
        diva_os_xdi_adapter_t *a = NULL;
        diva_os_spin_lock_magic_t old_irql;
        struct list_head *tmp;
@@ -401,21 +401,21 @@ void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
                         length, sizeof(diva_xdi_um_cfg_cmd_t)))
                        return NULL;
        }
-       if ((*cp_fn) (os_handle, &msg, src, sizeof(msg)) <= 0) {
+       if ((*cp_fn) (os_handle, msg, src, sizeof(*msg)) <= 0) {
                DBG_ERR(("A: A(?) open, write error"))
                        return NULL;
        }
        diva_os_enter_spin_lock(&adapter_lock, &old_irql, "open_adapter");
        list_for_each(tmp, &adapter_queue) {
                a = list_entry(tmp, diva_os_xdi_adapter_t, link);
-               if (a->controller == (int)msg.adapter)
+               if (a->controller == (int)msg->adapter)
                        break;
                a = NULL;
        }
        diva_os_leave_spin_lock(&adapter_lock, &old_irql, "open_adapter");
 
        if (!a) {
-               DBG_ERR(("A: A(%d) open, adapter not found", msg.adapter))
+               DBG_ERR(("A: A(%d) open, adapter not found", msg->adapter))
                        }
 
        return (a);
@@ -437,8 +437,10 @@ void diva_xdi_close_adapter(void *adapter, void *os_handle)
 
 int
 diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
-              int length, divas_xdi_copy_from_user_fn_t cp_fn)
+              int length, void *mptr,
+              divas_xdi_copy_from_user_fn_t cp_fn)
 {
+       diva_xdi_um_cfg_cmd_t *msg = (diva_xdi_um_cfg_cmd_t *)mptr;
        diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) adapter;
        void *data;
 
@@ -459,7 +461,13 @@ diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
                        return (-2);
        }
 
-       length = (*cp_fn) (os_handle, data, src, length);
+       if (msg) {
+               *(diva_xdi_um_cfg_cmd_t *)data = *msg;
+               length = (*cp_fn) (os_handle, (char *)data + sizeof(*msg),
+                                  src + sizeof(*msg), length - sizeof(*msg));
+       } else {
+               length = (*cp_fn) (os_handle, data, src, length);
+       }
        if (length > 0) {
                if ((*(a->interface.cmd_proc))
                    (a, (diva_xdi_um_cfg_cmd_t *) data, length)) {
index b067032093a8a2bb656f3e8c58fa91bccad7b056..1ad76650fbf984b3fe8b0385205005a57de52c0d 100644 (file)
@@ -20,10 +20,11 @@ int diva_xdi_read(void *adapter, void *os_handle, void __user *dst,
                  int max_length, divas_xdi_copy_to_user_fn_t cp_fn);
 
 int diva_xdi_write(void *adapter, void *os_handle, const void __user *src,
-                  int length, divas_xdi_copy_from_user_fn_t cp_fn);
+                  int length, void *msg,
+                  divas_xdi_copy_from_user_fn_t cp_fn);
 
 void *diva_xdi_open_adapter(void *os_handle, const void __user *src,
-                           int length,
+                           int length, void *msg,
                            divas_xdi_copy_from_user_fn_t cp_fn);
 
 void diva_xdi_close_adapter(void *adapter, void *os_handle);
index b9980e84f9db56570ef9c2dbc8b007e8818978d3..b6a3950b2564f9142f6e19b188becec62d01d3df 100644 (file)
@@ -591,19 +591,22 @@ static int divas_release(struct inode *inode, struct file *file)
 static ssize_t divas_write(struct file *file, const char __user *buf,
                           size_t count, loff_t *ppos)
 {
+       diva_xdi_um_cfg_cmd_t msg;
        int ret = -EINVAL;
 
        if (!file->private_data) {
                file->private_data = diva_xdi_open_adapter(file, buf,
-                                                          count,
+                                                          count, &msg,
                                                           xdi_copy_from_user);
-       }
-       if (!file->private_data) {
-               return (-ENODEV);
+               if (!file->private_data)
+                       return (-ENODEV);
+               ret = diva_xdi_write(file->private_data, file,
+                                    buf, count, &msg, xdi_copy_from_user);
+       } else {
+               ret = diva_xdi_write(file->private_data, file,
+                                    buf, count, NULL, xdi_copy_from_user);
        }
 
-       ret = diva_xdi_write(file->private_data, file,
-                            buf, count, xdi_copy_from_user);
        switch (ret) {
        case -1:                /* Message should be removed from rx mailbox first */
                ret = -EBUSY;
@@ -622,11 +625,12 @@ static ssize_t divas_write(struct file *file, const char __user *buf,
 static ssize_t divas_read(struct file *file, char __user *buf,
                          size_t count, loff_t *ppos)
 {
+       diva_xdi_um_cfg_cmd_t msg;
        int ret = -EINVAL;
 
        if (!file->private_data) {
                file->private_data = diva_xdi_open_adapter(file, buf,
-                                                          count,
+                                                          count, &msg,
                                                           xdi_copy_from_user);
        }
        if (!file->private_data) {
index 9e923cd1d80ebee9c96d70aceabb87b2a0935581..38a7586b00ccafd6bb0eed4307f9a40f91fee90a 100644 (file)
@@ -2485,7 +2485,7 @@ static long mmc_rpmb_ioctl(struct file *filp, unsigned int cmd,
                break;
        }
 
-       return 0;
+       return ret;
 }
 
 #ifdef CONFIG_COMPAT
index 0ef741bc515d9f354e03576bc2eb079b40a1d7e5..d0e83db42ae52614b5ab9f03d211290f7c100937 100644 (file)
@@ -33,6 +33,8 @@ struct sdhci_iproc_host {
        const struct sdhci_iproc_data *data;
        u32 shadow_cmd;
        u32 shadow_blk;
+       bool is_cmd_shadowed;
+       bool is_blk_shadowed;
 };
 
 #define REG_OFFSET_IN_BITS(reg) ((reg) << 3 & 0x18)
@@ -48,8 +50,22 @@ static inline u32 sdhci_iproc_readl(struct sdhci_host *host, int reg)
 
 static u16 sdhci_iproc_readw(struct sdhci_host *host, int reg)
 {
-       u32 val = sdhci_iproc_readl(host, (reg & ~3));
-       u16 word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_iproc_host *iproc_host = sdhci_pltfm_priv(pltfm_host);
+       u32 val;
+       u16 word;
+
+       if ((reg == SDHCI_TRANSFER_MODE) && iproc_host->is_cmd_shadowed) {
+               /* Get the saved transfer mode */
+               val = iproc_host->shadow_cmd;
+       } else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
+                  iproc_host->is_blk_shadowed) {
+               /* Get the saved block info */
+               val = iproc_host->shadow_blk;
+       } else {
+               val = sdhci_iproc_readl(host, (reg & ~3));
+       }
+       word = val >> REG_OFFSET_IN_BITS(reg) & 0xffff;
        return word;
 }
 
@@ -105,13 +121,15 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
 
        if (reg == SDHCI_COMMAND) {
                /* Write the block now as we are issuing a command */
-               if (iproc_host->shadow_blk != 0) {
+               if (iproc_host->is_blk_shadowed) {
                        sdhci_iproc_writel(host, iproc_host->shadow_blk,
                                SDHCI_BLOCK_SIZE);
-                       iproc_host->shadow_blk = 0;
+                       iproc_host->is_blk_shadowed = false;
                }
                oldval = iproc_host->shadow_cmd;
-       } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
+               iproc_host->is_cmd_shadowed = false;
+       } else if ((reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) &&
+                  iproc_host->is_blk_shadowed) {
                /* Block size and count are stored in shadow reg */
                oldval = iproc_host->shadow_blk;
        } else {
@@ -123,9 +141,11 @@ static void sdhci_iproc_writew(struct sdhci_host *host, u16 val, int reg)
        if (reg == SDHCI_TRANSFER_MODE) {
                /* Save the transfer mode until the command is issued */
                iproc_host->shadow_cmd = newval;
+               iproc_host->is_cmd_shadowed = true;
        } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) {
                /* Save the block info until the command is issued */
                iproc_host->shadow_blk = newval;
+               iproc_host->is_blk_shadowed = true;
        } else {
                /* Command or other regular 32-bit write */
                sdhci_iproc_writel(host, newval, reg & ~3);
@@ -166,7 +186,7 @@ static const struct sdhci_ops sdhci_iproc_32only_ops = {
 
 static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
        .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
-       .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,
+       .quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN | SDHCI_QUIRK2_HOST_OFF_CARD_ON,
        .ops = &sdhci_iproc_32only_ops,
 };
 
@@ -206,7 +226,6 @@ static const struct sdhci_iproc_data iproc_data = {
        .caps1 = SDHCI_DRIVER_TYPE_C |
                 SDHCI_DRIVER_TYPE_D |
                 SDHCI_SUPPORT_DDR50,
-       .mmc_caps = MMC_CAP_1_8V_DDR,
 };
 
 static const struct sdhci_pltfm_data sdhci_bcm2835_pltfm_data = {
index a561705f232cd89dbf26c8907a7de31591907a50..be198cc0b10c9c7664bdf80e0f93bb3db69e8cf9 100644 (file)
@@ -1552,22 +1552,26 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!ioaddr) {
                if (pcnet32_debug & NETIF_MSG_PROBE)
                        pr_err("card has no PCI IO resources, aborting\n");
-               return -ENODEV;
+               err = -ENODEV;
+               goto err_disable_dev;
        }
 
        err = pci_set_dma_mask(pdev, PCNET32_DMA_MASK);
        if (err) {
                if (pcnet32_debug & NETIF_MSG_PROBE)
                        pr_err("architecture does not support 32bit PCI busmaster DMA\n");
-               return err;
+               goto err_disable_dev;
        }
        if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) {
                if (pcnet32_debug & NETIF_MSG_PROBE)
                        pr_err("io address range already allocated\n");
-               return -EBUSY;
+               err = -EBUSY;
+               goto err_disable_dev;
        }
 
        err = pcnet32_probe1(ioaddr, 1, pdev);
+
+err_disable_dev:
        if (err < 0)
                pci_disable_device(pdev);
 
index 81684acf52afa576bda05d9c535a7890c5ee8deb..8a8b12b720ef99bb923a3a441c933ee36e596e80 100644 (file)
@@ -2747,11 +2747,11 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        pci_set_master(pdev);
 
        /* Query PCI controller on system for DMA addressing
-        * limitation for the device.  Try 64-bit first, and
+        * limitation for the device.  Try 47-bit first, and
         * fail to 32-bit.
         */
 
-       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(47));
        if (err) {
                err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (err) {
@@ -2765,10 +2765,10 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        goto err_out_release_regions;
                }
        } else {
-               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(47));
                if (err) {
                        dev_err(dev, "Unable to obtain %u-bit DMA "
-                               "for consistent allocations, aborting\n", 64);
+                               "for consistent allocations, aborting\n", 47);
                        goto err_out_release_regions;
                }
                using_dac = 1;
index d4604bc8eb5b04742534100c4c285065bda2021e..9d3eed46830d73041b53c12411bf68d8939041e2 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
  * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
index f81439796ac77dfdd47e9a350b576122bfc0b1d9..43d9732150404100fc09be91ebfa3e750b419577 100644 (file)
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Fast Ethernet Controller (ENET) PTP driver for MX6x.
  *
  * Copyright (C) 2012 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
index 4bb4646a5f92f5617b6a3306a5002e180fc9cca1..5ec1185808e5d13e82990732299c413f7d9120a1 100644 (file)
@@ -796,9 +796,11 @@ static int ibmvnic_login(struct net_device *netdev)
        struct ibmvnic_adapter *adapter = netdev_priv(netdev);
        unsigned long timeout = msecs_to_jiffies(30000);
        int retry_count = 0;
+       bool retry;
        int rc;
 
        do {
+               retry = false;
                if (retry_count > IBMVNIC_MAX_QUEUES) {
                        netdev_warn(netdev, "Login attempts exceeded\n");
                        return -1;
@@ -822,6 +824,9 @@ static int ibmvnic_login(struct net_device *netdev)
                        retry_count++;
                        release_sub_crqs(adapter, 1);
 
+                       retry = true;
+                       netdev_dbg(netdev,
+                                  "Received partial success, retrying...\n");
                        adapter->init_done_rc = 0;
                        reinit_completion(&adapter->init_done);
                        send_cap_queries(adapter);
@@ -849,7 +854,7 @@ static int ibmvnic_login(struct net_device *netdev)
                        netdev_warn(netdev, "Adapter login failed\n");
                        return -1;
                }
-       } while (adapter->init_done_rc == PARTIALSUCCESS);
+       } while (retry);
 
        /* handle pending MAC address changes after successful login */
        if (adapter->mac_change_pending) {
@@ -2617,18 +2622,21 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter,
 {
        struct device *dev = &adapter->vdev->dev;
        unsigned long rc;
-       u64 val;
 
        if (scrq->hw_irq > 0x100000000ULL) {
                dev_err(dev, "bad hw_irq = %lx\n", scrq->hw_irq);
                return 1;
        }
 
-       val = (0xff000000) | scrq->hw_irq;
-       rc = plpar_hcall_norets(H_EOI, val);
-       if (rc)
-               dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
-                       val, rc);
+       if (adapter->resetting &&
+           adapter->reset_reason == VNIC_RESET_MOBILITY) {
+               u64 val = (0xff000000) | scrq->hw_irq;
+
+               rc = plpar_hcall_norets(H_EOI, val);
+               if (rc)
+                       dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n",
+                               val, rc);
+       }
 
        rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address,
                                H_ENABLE_VIO_INTERRUPT, scrq->hw_irq, 0, 0);
index a822f7a56bc5bc7727bfcff9c148053776a9855e..685337d58276fc91baeeb64387c52985e1bc6dda 100644 (file)
 #include "fw.h"
 
 /*
- * We allocate in as big chunks as we can, up to a maximum of 256 KB
- * per chunk.
+ * We allocate in page size (default 4KB on many archs) chunks to avoid high
+ * order memory allocations in fragmented/high usage memory situation.
  */
 enum {
-       MLX4_ICM_ALLOC_SIZE     = 1 << 18,
-       MLX4_TABLE_CHUNK_SIZE   = 1 << 18
+       MLX4_ICM_ALLOC_SIZE     = PAGE_SIZE,
+       MLX4_TABLE_CHUNK_SIZE   = PAGE_SIZE,
 };
 
 static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chunk)
@@ -398,9 +398,11 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table,
        u64 size;
 
        obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size;
+       if (WARN_ON(!obj_per_chunk))
+               return -EINVAL;
        num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk;
 
-       table->icm      = kcalloc(num_icm, sizeof(*table->icm), GFP_KERNEL);
+       table->icm      = kvzalloc(num_icm * sizeof(*table->icm), GFP_KERNEL);
        if (!table->icm)
                return -ENOMEM;
        table->virt     = virt;
@@ -446,7 +448,7 @@ err:
                        mlx4_free_icm(dev, table->icm[i], use_coherent);
                }
 
-       kfree(table->icm);
+       kvfree(table->icm);
 
        return -ENOMEM;
 }
@@ -462,5 +464,5 @@ void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table)
                        mlx4_free_icm(dev, table->icm[i], table->coherent);
                }
 
-       kfree(table->icm);
+       kvfree(table->icm);
 }
index 2edcce98ab2d6a33599ca874b5a7d9b2359f6c52..65482f004e50a11bc3f13b7253716c89a0a02338 100644 (file)
@@ -172,7 +172,7 @@ int mlx4_do_bond(struct mlx4_dev *dev, bool enable)
                list_add_tail(&dev_ctx->list, &priv->ctx_list);
                spin_unlock_irqrestore(&priv->ctx_lock, flags);
 
-               mlx4_dbg(dev, "Inrerface for protocol %d restarted with when bonded mode is %s\n",
+               mlx4_dbg(dev, "Interface for protocol %d restarted with bonded mode %s\n",
                         dev_ctx->intf->protocol, enable ?
                         "enabled" : "disabled");
        }
index 3aaf4bad6c5a5bd7cbdf111a8f6411697a3b4289..427e7a31862c2a000bc51d068c7254e8e72a9e6a 100644 (file)
@@ -393,11 +393,11 @@ struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
        struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
        struct mlx4_qp *qp;
 
-       spin_lock(&qp_table->lock);
+       spin_lock_irq(&qp_table->lock);
 
        qp = __mlx4_qp_lookup(dev, qpn);
 
-       spin_unlock(&qp_table->lock);
+       spin_unlock_irq(&qp_table->lock);
        return qp;
 }
 
index 176645762e491687dae7ae0fb28da282fa29c49f..1ff0b0e9380410510c094ea1cb5699545ef9fc4f 100644 (file)
@@ -615,6 +615,45 @@ static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth)
        return (ethertype == htons(ETH_P_IP) || ethertype == htons(ETH_P_IPV6));
 }
 
+static __be32 mlx5e_get_fcs(struct sk_buff *skb)
+{
+       int last_frag_sz, bytes_in_prev, nr_frags;
+       u8 *fcs_p1, *fcs_p2;
+       skb_frag_t *last_frag;
+       __be32 fcs_bytes;
+
+       if (!skb_is_nonlinear(skb))
+               return *(__be32 *)(skb->data + skb->len - ETH_FCS_LEN);
+
+       nr_frags = skb_shinfo(skb)->nr_frags;
+       last_frag = &skb_shinfo(skb)->frags[nr_frags - 1];
+       last_frag_sz = skb_frag_size(last_frag);
+
+       /* If all FCS data is in last frag */
+       if (last_frag_sz >= ETH_FCS_LEN)
+               return *(__be32 *)(skb_frag_address(last_frag) +
+                                  last_frag_sz - ETH_FCS_LEN);
+
+       fcs_p2 = (u8 *)skb_frag_address(last_frag);
+       bytes_in_prev = ETH_FCS_LEN - last_frag_sz;
+
+       /* Find where the other part of the FCS is - Linear or another frag */
+       if (nr_frags == 1) {
+               fcs_p1 = skb_tail_pointer(skb);
+       } else {
+               skb_frag_t *prev_frag = &skb_shinfo(skb)->frags[nr_frags - 2];
+
+               fcs_p1 = skb_frag_address(prev_frag) +
+                           skb_frag_size(prev_frag);
+       }
+       fcs_p1 -= bytes_in_prev;
+
+       memcpy(&fcs_bytes, fcs_p1, bytes_in_prev);
+       memcpy(((u8 *)&fcs_bytes) + bytes_in_prev, fcs_p2, last_frag_sz);
+
+       return fcs_bytes;
+}
+
 static inline void mlx5e_handle_csum(struct net_device *netdev,
                                     struct mlx5_cqe64 *cqe,
                                     struct mlx5e_rq *rq,
@@ -643,6 +682,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
                        skb->csum = csum_partial(skb->data + ETH_HLEN,
                                                 network_depth - ETH_HLEN,
                                                 skb->csum);
+               if (unlikely(netdev->features & NETIF_F_RXFCS))
+                       skb->csum = csum_add(skb->csum,
+                                            (__force __wsum)mlx5e_get_fcs(skb));
                rq->stats.csum_complete++;
                return;
        }
index 0f5da499a22339fa11eb30fa73334b5d8ec4c039..fad8c2e3804e4f49da4461976da18c3e6316264c 100644 (file)
@@ -237,19 +237,17 @@ static void *mlx5_fpga_ipsec_cmd_exec(struct mlx5_core_dev *mdev,
        context->buf.sg[0].data = &context->command;
 
        spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags);
-       list_add_tail(&context->list, &fdev->ipsec->pending_cmds);
+       res = mlx5_fpga_sbu_conn_sendmsg(fdev->ipsec->conn, &context->buf);
+       if (!res)
+               list_add_tail(&context->list, &fdev->ipsec->pending_cmds);
        spin_unlock_irqrestore(&fdev->ipsec->pending_cmds_lock, flags);
 
-       res = mlx5_fpga_sbu_conn_sendmsg(fdev->ipsec->conn, &context->buf);
        if (res) {
-               mlx5_fpga_warn(fdev, "Failure sending IPSec command: %d\n",
-                              res);
-               spin_lock_irqsave(&fdev->ipsec->pending_cmds_lock, flags);
-               list_del(&context->list);
-               spin_unlock_irqrestore(&fdev->ipsec->pending_cmds_lock, flags);
+               mlx5_fpga_warn(fdev, "Failed to send IPSec command: %d\n", res);
                kfree(context);
                return ERR_PTR(res);
        }
+
        /* Context will be freed by wait func after completion */
        return context;
 }
index 00f41c145d4d01674d146fe1eda41a346b3cc5a1..820b226d6ff8c91952b266e585a5c2ea91b625cb 100644 (file)
@@ -77,7 +77,7 @@
 #define ILT_CFG_REG(cli, reg)  PSWRQ2_REG_ ## cli ## _ ## reg ## _RT_OFFSET
 
 /* ILT entry structure */
-#define ILT_ENTRY_PHY_ADDR_MASK                0x000FFFFFFFFFFFULL
+#define ILT_ENTRY_PHY_ADDR_MASK                (~0ULL >> 12)
 #define ILT_ENTRY_PHY_ADDR_SHIFT       0
 #define ILT_ENTRY_VALID_MASK           0x1ULL
 #define ILT_ENTRY_VALID_SHIFT          52
index 6838129839ca457b7c06ddfbddeb8936f60b4f19..e757b09f188944befe4f769b8637c98adbf3f627 100644 (file)
@@ -61,17 +61,17 @@ static int bcm_cygnus_afe_config(struct phy_device *phydev)
                return rc;
 
        /* make rcal=100, since rdb default is 000 */
-       rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB1, 0x10);
+       rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB1, 0x10);
        if (rc < 0)
                return rc;
 
        /* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */
-       rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x10);
+       rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x10);
        if (rc < 0)
                return rc;
 
        /* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */
-       rc = bcm_phy_write_exp(phydev, MII_BRCM_CORE_EXPB0, 0x00);
+       rc = bcm_phy_write_exp_sel(phydev, MII_BRCM_CORE_EXPB0, 0x00);
 
        return 0;
 }
index 5ad130c3da43c869b39dc8ec83ec6795aa82be7d..d5e0833d69b9b8a27c36842286d29029402a3156 100644 (file)
@@ -56,7 +56,7 @@ int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
        /* The register must be written to both the Shadow Register Select and
         * the Shadow Read Register Selector
         */
-       phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum |
+       phy_write(phydev, MII_BCM54XX_AUX_CTL, MII_BCM54XX_AUXCTL_SHDWSEL_MASK |
                  regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
        return phy_read(phydev, MII_BCM54XX_AUX_CTL);
 }
index 7c73808cbbded22bb01b60ef2b616456267f99cc..81cceaa412fe32439a31561416610198c6c6c3e5 100644 (file)
 #ifndef _LINUX_BCM_PHY_LIB_H
 #define _LINUX_BCM_PHY_LIB_H
 
+#include <linux/brcmphy.h>
 #include <linux/phy.h>
 
 int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val);
 int bcm_phy_read_exp(struct phy_device *phydev, u16 reg);
 
+static inline int bcm_phy_write_exp_sel(struct phy_device *phydev,
+                                       u16 reg, u16 val)
+{
+       return bcm_phy_write_exp(phydev, reg | MII_BCM54XX_EXP_SEL_ER, val);
+}
+
 int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val);
 int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum);
 
index 29b1c88b55cc494bae079da9b2283170508b4e9d..01d2ff2f62413226caecebe5e18b45ccfb12c808 100644 (file)
@@ -65,10 +65,10 @@ struct bcm7xxx_phy_priv {
 static void r_rc_cal_reset(struct phy_device *phydev)
 {
        /* Reset R_CAL/RC_CAL Engine */
-       bcm_phy_write_exp(phydev, 0x00b0, 0x0010);
+       bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0010);
 
        /* Disable Reset R_AL/RC_CAL Engine */
-       bcm_phy_write_exp(phydev, 0x00b0, 0x0000);
+       bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0000);
 }
 
 static int bcm7xxx_28nm_b0_afe_config_init(struct phy_device *phydev)
index dc7c7ec432023a7ac8e7a63410f7ec04437ea7b7..02ad03a2fab773cd36707e50434cc559fc639f7c 100644 (file)
@@ -605,30 +605,13 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
        if (cmd == PPPIOCDETACH) {
                /*
-                * We have to be careful here... if the file descriptor
-                * has been dup'd, we could have another process in the
-                * middle of a poll using the same file *, so we had
-                * better not free the interface data structures -
-                * instead we fail the ioctl.  Even in this case, we
-                * shut down the interface if we are the owner of it.
-                * Actually, we should get rid of PPPIOCDETACH, userland
-                * (i.e. pppd) could achieve the same effect by closing
-                * this fd and reopening /dev/ppp.
+                * PPPIOCDETACH is no longer supported as it was heavily broken,
+                * and is only known to have been used by pppd older than
+                * ppp-2.4.2 (released November 2003).
                 */
+               pr_warn_once("%s (%d) used obsolete PPPIOCDETACH ioctl\n",
+                            current->comm, current->pid);
                err = -EINVAL;
-               if (pf->kind == INTERFACE) {
-                       ppp = PF_TO_PPP(pf);
-                       rtnl_lock();
-                       if (file == ppp->owner)
-                               unregister_netdevice(ppp->dev);
-                       rtnl_unlock();
-               }
-               if (atomic_long_read(&file->f_count) < 2) {
-                       ppp_release(NULL, file);
-                       err = 0;
-               } else
-                       pr_warn("PPPIOCDETACH file->f_count=%ld\n",
-                               atomic_long_read(&file->f_count));
                goto out;
        }
 
index d45ac37e128740884d5570dd14cdbc11aac1fa6b..45d807796a18a1584ea7af3d43cb0b8daab9ca8f 100644 (file)
@@ -1423,6 +1423,13 @@ static void tun_net_init(struct net_device *dev)
        dev->max_mtu = MAX_MTU - dev->hard_header_len;
 }
 
+static bool tun_sock_writeable(struct tun_struct *tun, struct tun_file *tfile)
+{
+       struct sock *sk = tfile->socket.sk;
+
+       return (tun->dev->flags & IFF_UP) && sock_writeable(sk);
+}
+
 /* Character device part */
 
 /* Poll */
@@ -1445,10 +1452,14 @@ static __poll_t tun_chr_poll(struct file *file, poll_table *wait)
        if (!ptr_ring_empty(&tfile->tx_ring))
                mask |= EPOLLIN | EPOLLRDNORM;
 
-       if (tun->dev->flags & IFF_UP &&
-           (sock_writeable(sk) ||
-            (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
-             sock_writeable(sk))))
+       /* Make sure SOCKWQ_ASYNC_NOSPACE is set if not writable to
+        * guarantee EPOLLOUT to be raised by either here or
+        * tun_sock_write_space(). Then process could get notification
+        * after it writes to a down device and meets -EIO.
+        */
+       if (tun_sock_writeable(tun, tfile) ||
+           (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
+            tun_sock_writeable(tun, tfile)))
                mask |= EPOLLOUT | EPOLLWRNORM;
 
        if (tun->dev->reg_state != NETREG_REGISTERED)
index 770422e953f75e1e9a1bb3a317d83f8070e6ae36..032e1ac10a3091ef48346c48756d18fd9c038246 100644 (file)
@@ -707,6 +707,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                void *data;
                u32 act;
 
+               /* Transient failure which in theory could occur if
+                * in-flight packets from before XDP was enabled reach
+                * the receive path after XDP is loaded.
+                */
+               if (unlikely(hdr->hdr.gso_type))
+                       goto err_xdp;
+
                /* This happens when rx buffer size is underestimated
                 * or headroom is not enough because of the buffer
                 * was refilled before XDP is set. This should only
@@ -727,14 +734,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                        xdp_page = page;
                }
 
-               /* Transient failure which in theory could occur if
-                * in-flight packets from before XDP was enabled reach
-                * the receive path after XDP is loaded. In practice I
-                * was not able to create this condition.
-                */
-               if (unlikely(hdr->hdr.gso_type))
-                       goto err_xdp;
-
                /* Allow consuming headroom but reserve enough space to push
                 * the descriptor on if we get an XDP_TX return code.
                 */
@@ -775,7 +774,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                        }
                        *xdp_xmit = true;
                        if (unlikely(xdp_page != page))
-                               goto err_xdp;
+                               put_page(page);
                        rcu_read_unlock();
                        goto xdp_xmit;
                case XDP_REDIRECT:
@@ -787,7 +786,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
                        }
                        *xdp_xmit = true;
                        if (unlikely(xdp_page != page))
-                               goto err_xdp;
+                               put_page(page);
                        rcu_read_unlock();
                        goto xdp_xmit;
                default:
@@ -875,7 +874,7 @@ err_xdp:
        rcu_read_unlock();
 err_skb:
        put_page(page);
-       while (--num_buf) {
+       while (num_buf-- > 1) {
                buf = virtqueue_get_buf(rq->vq, &len);
                if (unlikely(!buf)) {
                        pr_debug("%s: rx error: %d buffers missing\n",
index 4a017a0d71ea47ae270119593f4c9e1db3632513..920c23e542a57755bd29946a5b46492b0133251b 100644 (file)
@@ -3340,7 +3340,7 @@ out_err:
 static int hwsim_dump_radio_nl(struct sk_buff *skb,
                               struct netlink_callback *cb)
 {
-       int last_idx = cb->args[0];
+       int last_idx = cb->args[0] - 1;
        struct mac80211_hwsim_data *data = NULL;
        int res = 0;
        void *hdr;
@@ -3368,7 +3368,7 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
                last_idx = data->idx;
        }
 
-       cb->args[0] = last_idx;
+       cb->args[0] = last_idx + 1;
 
        /* list changed, but no new element sent, set interrupted flag */
        if (skb->len == 0 && cb->prev_seq && cb->seq != cb->prev_seq) {
index 9371651d801776702dd34cde1d04d3501f1c54ef..c574dd210500ad836a17cf89d7f2d70a5dc0effb 100644 (file)
@@ -117,7 +117,7 @@ config SSB_SERIAL
 
 config SSB_DRIVER_PCICORE_POSSIBLE
        bool
-       depends on SSB_PCIHOST && SSB = y
+       depends on SSB_PCIHOST
        default y
 
 config SSB_DRIVER_PCICORE
@@ -131,7 +131,7 @@ config SSB_DRIVER_PCICORE
 
 config SSB_PCICORE_HOSTMODE
        bool "Hostmode support for SSB PCI core"
-       depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS
+       depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS && SSB = y
        help
          PCIcore hostmode operation (external PCI bus).
 
index f3bd8e9412245919ba3a73fb9d94677c280d1427..f0be5f35ab28f2a009a0e56d75bbb0c46fbcb4d9 100644 (file)
@@ -981,6 +981,7 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
 {
        int ret = 0;
 
+       mutex_lock(&dev->mutex);
        vhost_dev_lock_vqs(dev);
        switch (msg->type) {
        case VHOST_IOTLB_UPDATE:
@@ -1016,6 +1017,8 @@ static int vhost_process_iotlb_msg(struct vhost_dev *dev,
        }
 
        vhost_dev_unlock_vqs(dev);
+       mutex_unlock(&dev->mutex);
+
        return ret;
 }
 ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
index 91a8889abf9ba9f4d3df399996346942f48c2555..ea8c551bcd7e4302f5b460a3c145ef2dbf0d4398 100644 (file)
@@ -570,16 +570,7 @@ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
                     current_page, vec_len, vec_start);
 
                len = bio_add_page(bio, page, vec_len, vec_start);
-               if (len != vec_len) {
-                       mlog(ML_ERROR, "Adding page[%d] to bio failed, "
-                            "page %p, len %d, vec_len %u, vec_start %u, "
-                            "bi_sector %llu\n", current_page, page, len,
-                            vec_len, vec_start,
-                            (unsigned long long)bio->bi_iter.bi_sector);
-                       bio_put(bio);
-                       bio = ERR_PTR(-EIO);
-                       return bio;
-               }
+               if (len != vec_len) break;
 
                cs += vec_len / (PAGE_SIZE/spp);
                vec_start = 0;
index c6c27f1f9c9850634700e4898adae6ab7755e113..4cc090b50cc528a2185a567656f835790e0f09bc 100644 (file)
@@ -709,11 +709,6 @@ void seq_put_decimal_ull_width(struct seq_file *m, const char *delimiter,
        if (m->count + width >= m->size)
                goto overflow;
 
-       if (num < 10) {
-               m->buf[m->count++] = num + '0';
-               return;
-       }
-
        len = num_to_str(m->buf + m->count, m->size - m->count, num, width);
        if (!len)
                goto overflow;
index 65cfc2f59db945e1d21d6847e4b13fa7a1a23fc8..df36b1b08af0554fd60ac05c6ee8233154db70d2 100644 (file)
@@ -142,7 +142,7 @@ struct bpf_verifier_state_list {
 struct bpf_insn_aux_data {
        union {
                enum bpf_reg_type ptr_type;     /* pointer type for load/store insns */
-               struct bpf_map *map_ptr;        /* pointer for call insn into lookup_elem */
+               unsigned long map_state;        /* pointer/poison value for maps */
                s32 call_imm;                   /* saved imm field of call insn */
        };
        int ctx_field_size; /* the ctx field size for load insn, maybe 0 */
index 1a4582b44d3273d41d5e0e65ca38857cee14561e..fc5ab85278d5fb2ff1f32c1f66b1aca1befc21a0 100644 (file)
@@ -464,7 +464,7 @@ static inline struct page *
 __alloc_pages_node(int nid, gfp_t gfp_mask, unsigned int order)
 {
        VM_BUG_ON(nid < 0 || nid >= MAX_NUMNODES);
-       VM_WARN_ON(!node_online(nid));
+       VM_WARN_ON((gfp_mask & __GFP_THISNODE) && !node_online(nid));
 
        return __alloc_pages(gfp_mask, order, nid);
 }
index 41f171861dccdc4aa6727303e2261e702bbfe6bd..6d336e38d155e46ad4deff6dbabb7bf413795b5b 100644 (file)
@@ -32,9 +32,11 @@ extern struct node *node_devices[];
 typedef  void (*node_registration_func_t)(struct node *);
 
 #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
-extern int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages);
+extern int link_mem_sections(int nid, unsigned long start_pfn,
+                            unsigned long nr_pages, bool check_nid);
 #else
-static inline int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages)
+static inline int link_mem_sections(int nid, unsigned long start_pfn,
+                                   unsigned long nr_pages, bool check_nid)
 {
        return 0;
 }
@@ -57,7 +59,7 @@ static inline int register_one_node(int nid)
                if (error)
                        return error;
                /* link memory sections under this node */
-               error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages);
+               error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages, true);
        }
 
        return error;
index 28b996d6349072fb031de91e10115b688d89b42d..35498e613ff5458e5433facbf409e9c90a5153b7 100644 (file)
@@ -103,6 +103,8 @@ void sctp_addr_wq_mgmt(struct net *, struct sctp_sockaddr_entry *, int);
 /*
  * sctp/socket.c
  */
+int sctp_inet_connect(struct socket *sock, struct sockaddr *uaddr,
+                     int addr_len, int flags);
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb);
 int sctp_inet_listen(struct socket *sock, int backlog);
 void sctp_write_space(struct sock *sk);
index 9c3630146cec0f739a0c3cea6ec98e95e69e44bb..271b93783d282d113bddd8a4bc0db780cd52a397 100644 (file)
@@ -2698,7 +2698,7 @@ enum nl80211_attrs {
 #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
 #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS
 
-#define NL80211_WIPHY_NAME_MAXLEN              128
+#define NL80211_WIPHY_NAME_MAXLEN              64
 
 #define NL80211_MAX_SUPP_RATES                 32
 #define NL80211_MAX_SUPP_HT_RATES              77
index b19a9c249b156f5877a0e8651a1d4d2330f6088d..784c2e3e572e013a24aeabf96ef400f453ffb72e 100644 (file)
@@ -106,7 +106,7 @@ struct pppol2tp_ioc_stats {
 #define PPPIOCGIDLE    _IOR('t', 63, struct ppp_idle) /* get idle time */
 #define PPPIOCNEWUNIT  _IOWR('t', 62, int)     /* create new ppp unit */
 #define PPPIOCATTACH   _IOW('t', 61, int)      /* attach to ppp unit */
-#define PPPIOCDETACH   _IOW('t', 60, int)      /* detach from ppp unit/chan */
+#define PPPIOCDETACH   _IOW('t', 60, int)      /* obsolete, do not use */
 #define PPPIOCSMRRU    _IOW('t', 59, int)      /* set multilink MRU */
 #define PPPIOCCONNECT  _IOW('t', 58, int)      /* connect channel to unit */
 #define PPPIOCDISCONN  _IO('t', 57)            /* disconnect channel */
index fd37315835b4ae18235af293cc689b6cdd055850..3b4ada11ed521a1bb25ead3ca461640ba1026923 100644 (file)
@@ -91,6 +91,7 @@
 #include <linux/cache.h>
 #include <linux/rodata_test.h>
 #include <linux/jump_label.h>
+#include <linux/mem_encrypt.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
index 3cf48988d68cec1e3a899f932de846818d4c729a..d73269381ec7ed831eaa65e544aa8b5ab4e504dd 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1363,14 +1363,17 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
 
        if (addr) {
                if (addr & (shmlba - 1)) {
-                       /*
-                        * Round down to the nearest multiple of shmlba.
-                        * For sane do_mmap_pgoff() parameters, avoid
-                        * round downs that trigger nil-page and MAP_FIXED.
-                        */
-                       if ((shmflg & SHM_RND) && addr >= shmlba)
-                               addr &= ~(shmlba - 1);
-                       else
+                       if (shmflg & SHM_RND) {
+                               addr &= ~(shmlba - 1);  /* round down */
+
+                               /*
+                                * Ensure that the round-down is non-nil
+                                * when remapping. This can happen for
+                                * cases when addr < shmlba.
+                                */
+                               if (!addr && (shmflg & SHM_REMAP))
+                                       goto out;
+                       } else
 #ifndef __ARCH_FORCE_SHMLBA
                                if (addr & ~PAGE_MASK)
 #endif
index 2ce967a63ede004f94a242a744e1681ab8a31334..1904e814f2828c01027c3c6b5002198b5233703b 100644 (file)
@@ -156,7 +156,29 @@ struct bpf_verifier_stack_elem {
 #define BPF_COMPLEXITY_LIMIT_INSNS     131072
 #define BPF_COMPLEXITY_LIMIT_STACK     1024
 
-#define BPF_MAP_PTR_POISON ((void *)0xeB9F + POISON_POINTER_DELTA)
+#define BPF_MAP_PTR_UNPRIV     1UL
+#define BPF_MAP_PTR_POISON     ((void *)((0xeB9FUL << 1) +     \
+                                         POISON_POINTER_DELTA))
+#define BPF_MAP_PTR(X)         ((struct bpf_map *)((X) & ~BPF_MAP_PTR_UNPRIV))
+
+static bool bpf_map_ptr_poisoned(const struct bpf_insn_aux_data *aux)
+{
+       return BPF_MAP_PTR(aux->map_state) == BPF_MAP_PTR_POISON;
+}
+
+static bool bpf_map_ptr_unpriv(const struct bpf_insn_aux_data *aux)
+{
+       return aux->map_state & BPF_MAP_PTR_UNPRIV;
+}
+
+static void bpf_map_ptr_store(struct bpf_insn_aux_data *aux,
+                             const struct bpf_map *map, bool unpriv)
+{
+       BUILD_BUG_ON((unsigned long)BPF_MAP_PTR_POISON & BPF_MAP_PTR_UNPRIV);
+       unpriv |= bpf_map_ptr_unpriv(aux);
+       aux->map_state = (unsigned long)map |
+                        (unpriv ? BPF_MAP_PTR_UNPRIV : 0UL);
+}
 
 struct bpf_call_arg_meta {
        struct bpf_map *map_ptr;
@@ -2358,6 +2380,29 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
        return 0;
 }
 
+static int
+record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
+               int func_id, int insn_idx)
+{
+       struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
+
+       if (func_id != BPF_FUNC_tail_call &&
+           func_id != BPF_FUNC_map_lookup_elem)
+               return 0;
+       if (meta->map_ptr == NULL) {
+               verbose(env, "kernel subsystem misconfigured verifier\n");
+               return -EINVAL;
+       }
+
+       if (!BPF_MAP_PTR(aux->map_state))
+               bpf_map_ptr_store(aux, meta->map_ptr,
+                                 meta->map_ptr->unpriv_array);
+       else if (BPF_MAP_PTR(aux->map_state) != meta->map_ptr)
+               bpf_map_ptr_store(aux, BPF_MAP_PTR_POISON,
+                                 meta->map_ptr->unpriv_array);
+       return 0;
+}
+
 static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn_idx)
 {
        const struct bpf_func_proto *fn = NULL;
@@ -2412,13 +2457,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
        err = check_func_arg(env, BPF_REG_2, fn->arg2_type, &meta);
        if (err)
                return err;
-       if (func_id == BPF_FUNC_tail_call) {
-               if (meta.map_ptr == NULL) {
-                       verbose(env, "verifier bug\n");
-                       return -EINVAL;
-               }
-               env->insn_aux_data[insn_idx].map_ptr = meta.map_ptr;
-       }
        err = check_func_arg(env, BPF_REG_3, fn->arg3_type, &meta);
        if (err)
                return err;
@@ -2429,6 +2467,10 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
        if (err)
                return err;
 
+       err = record_func_map(env, &meta, func_id, insn_idx);
+       if (err)
+               return err;
+
        /* Mark slots with STACK_MISC in case of raw mode, stack offset
         * is inferred from register state.
         */
@@ -2453,8 +2495,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
        } else if (fn->ret_type == RET_VOID) {
                regs[BPF_REG_0].type = NOT_INIT;
        } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) {
-               struct bpf_insn_aux_data *insn_aux;
-
                regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
                /* There is no offset yet applied, variable or fixed */
                mark_reg_known_zero(env, regs, BPF_REG_0);
@@ -2470,11 +2510,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
                }
                regs[BPF_REG_0].map_ptr = meta.map_ptr;
                regs[BPF_REG_0].id = ++env->id_gen;
-               insn_aux = &env->insn_aux_data[insn_idx];
-               if (!insn_aux->map_ptr)
-                       insn_aux->map_ptr = meta.map_ptr;
-               else if (insn_aux->map_ptr != meta.map_ptr)
-                       insn_aux->map_ptr = BPF_MAP_PTR_POISON;
        } else {
                verbose(env, "unknown return type %d of func %s#%d\n",
                        fn->ret_type, func_id_name(func_id), func_id);
@@ -5470,6 +5505,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
        struct bpf_insn *insn = prog->insnsi;
        const struct bpf_func_proto *fn;
        const int insn_cnt = prog->len;
+       struct bpf_insn_aux_data *aux;
        struct bpf_insn insn_buf[16];
        struct bpf_prog *new_prog;
        struct bpf_map *map_ptr;
@@ -5544,19 +5580,22 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
                        insn->imm = 0;
                        insn->code = BPF_JMP | BPF_TAIL_CALL;
 
+                       aux = &env->insn_aux_data[i + delta];
+                       if (!bpf_map_ptr_unpriv(aux))
+                               continue;
+
                        /* instead of changing every JIT dealing with tail_call
                         * emit two extra insns:
                         * if (index >= max_entries) goto out;
                         * index &= array->index_mask;
                         * to avoid out-of-bounds cpu speculation
                         */
-                       map_ptr = env->insn_aux_data[i + delta].map_ptr;
-                       if (map_ptr == BPF_MAP_PTR_POISON) {
+                       if (bpf_map_ptr_poisoned(aux)) {
                                verbose(env, "tail_call abusing map_ptr\n");
                                return -EINVAL;
                        }
-                       if (!map_ptr->unpriv_array)
-                               continue;
+
+                       map_ptr = BPF_MAP_PTR(aux->map_state);
                        insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3,
                                                  map_ptr->max_entries, 2);
                        insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3,
@@ -5580,9 +5619,12 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
                 */
                if (prog->jit_requested && BITS_PER_LONG == 64 &&
                    insn->imm == BPF_FUNC_map_lookup_elem) {
-                       map_ptr = env->insn_aux_data[i + delta].map_ptr;
-                       if (map_ptr == BPF_MAP_PTR_POISON ||
-                           !map_ptr->ops->map_gen_lookup)
+                       aux = &env->insn_aux_data[i + delta];
+                       if (bpf_map_ptr_poisoned(aux))
+                               goto patch_call_imm;
+
+                       map_ptr = BPF_MAP_PTR(aux->map_state);
+                       if (!map_ptr->ops->map_gen_lookup)
                                goto patch_call_imm;
 
                        cnt = map_ptr->ops->map_gen_lookup(map_ptr, insn_buf);
index b0eee418ee0d13609d67754cef43c5af39a582e7..d1b2b8d934bb7c660674583b5bd09d28c9f22167 100644 (file)
@@ -71,6 +71,9 @@
 #include <asm/io.h>
 #include <asm/unistd.h>
 
+/* Hardening for Spectre-v1 */
+#include <linux/nospec.h>
+
 #include "uid16.h"
 
 #ifndef SET_UNALIGN_CTL
@@ -1453,6 +1456,7 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
        if (resource >= RLIM_NLIMITS)
                return -EINVAL;
 
+       resource = array_index_nospec(resource, RLIM_NLIMITS);
        task_lock(current->group_leader);
        x = current->signal->rlim[resource];
        task_unlock(current->group_leader);
@@ -1472,6 +1476,7 @@ COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
        if (resource >= RLIM_NLIMITS)
                return -EINVAL;
 
+       resource = array_index_nospec(resource, RLIM_NLIMITS);
        task_lock(current->group_leader);
        r = current->signal->rlim[resource];
        task_unlock(current->group_leader);
index 43e0cbedc3a0ce1adf0d7807b623c9f8b60f3e53..a9e41aed6de4bfb063af9d16d41942a041a23fdd 100644 (file)
@@ -2034,10 +2034,12 @@ void *radix_tree_delete_item(struct radix_tree_root *root,
                             unsigned long index, void *item)
 {
        struct radix_tree_node *node = NULL;
-       void __rcu **slot;
+       void __rcu **slot = NULL;
        void *entry;
 
        entry = __radix_tree_lookup(root, index, &node, &slot);
+       if (!slot)
+               return NULL;
        if (!entry && (!is_idr(root) || node_tag_get(root, node, IDR_FREE,
                                                get_slot_offset(node, slot))))
                return NULL;
index bc0e68f7dc756104ff47005a4f9403af7e08fe4e..f185455b34065d27efa2b6a90c9dd2c1dfe92ae9 100644 (file)
@@ -792,6 +792,40 @@ DEFINE_ASAN_SET_SHADOW(f5);
 DEFINE_ASAN_SET_SHADOW(f8);
 
 #ifdef CONFIG_MEMORY_HOTPLUG
+static bool shadow_mapped(unsigned long addr)
+{
+       pgd_t *pgd = pgd_offset_k(addr);
+       p4d_t *p4d;
+       pud_t *pud;
+       pmd_t *pmd;
+       pte_t *pte;
+
+       if (pgd_none(*pgd))
+               return false;
+       p4d = p4d_offset(pgd, addr);
+       if (p4d_none(*p4d))
+               return false;
+       pud = pud_offset(p4d, addr);
+       if (pud_none(*pud))
+               return false;
+
+       /*
+        * We can't use pud_large() or pud_huge(), the first one is
+        * arch-specific, the last one depends on HUGETLB_PAGE.  So let's abuse
+        * pud_bad(), if pud is bad then it's bad because it's huge.
+        */
+       if (pud_bad(*pud))
+               return true;
+       pmd = pmd_offset(pud, addr);
+       if (pmd_none(*pmd))
+               return false;
+
+       if (pmd_bad(*pmd))
+               return true;
+       pte = pte_offset_kernel(pmd, addr);
+       return !pte_none(*pte);
+}
+
 static int __meminit kasan_mem_notifier(struct notifier_block *nb,
                        unsigned long action, void *data)
 {
@@ -813,6 +847,14 @@ static int __meminit kasan_mem_notifier(struct notifier_block *nb,
        case MEM_GOING_ONLINE: {
                void *ret;
 
+               /*
+                * If shadow is mapped already than it must have been mapped
+                * during the boot. This could happen if we onlining previously
+                * offlined memory.
+                */
+               if (shadow_mapped(shadow_start))
+                       return NOTIFY_OK;
+
                ret = __vmalloc_node_range(shadow_size, PAGE_SIZE, shadow_start,
                                        shadow_end, GFP_KERNEL,
                                        PAGE_KERNEL, VM_NO_GUARD,
@@ -824,8 +866,26 @@ static int __meminit kasan_mem_notifier(struct notifier_block *nb,
                kmemleak_ignore(ret);
                return NOTIFY_OK;
        }
-       case MEM_OFFLINE:
-               vfree((void *)shadow_start);
+       case MEM_CANCEL_ONLINE:
+       case MEM_OFFLINE: {
+               struct vm_struct *vm;
+
+               /*
+                * shadow_start was either mapped during boot by kasan_init()
+                * or during memory online by __vmalloc_node_range().
+                * In the latter case we can use vfree() to free shadow.
+                * Non-NULL result of the find_vm_area() will tell us if
+                * that was the second case.
+                *
+                * Currently it's not possible to free shadow mapped
+                * during boot by kasan_init(). It's because the code
+                * to do that hasn't been written yet. So we'll just
+                * leak the memory.
+                */
+               vm = find_vm_area((void *)shadow_start);
+               if (vm)
+                       vfree((void *)shadow_start);
+       }
        }
 
        return NOTIFY_OK;
@@ -838,5 +898,5 @@ static int __init kasan_memhotplug_init(void)
        return 0;
 }
 
-module_init(kasan_memhotplug_init);
+core_initcall(kasan_memhotplug_init);
 #endif
index f74826cdceea1112e648462393f46f034e4d46c2..25982467800b35756ad1eaf31a8782aaa52e0318 100644 (file)
@@ -1158,7 +1158,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
                 * nodes have to go through register_node.
                 * TODO clean up this mess.
                 */
-               ret = link_mem_sections(nid, start_pfn, nr_pages);
+               ret = link_mem_sections(nid, start_pfn, nr_pages, false);
 register_fail:
                /*
                 * If sysfs file of new node can't create, cpu on the node
index 511a7124d7f9029a110df3b4582a1b457831884f..22320ea27489acdcce17eccdec5ef7cb95bfc782 100644 (file)
@@ -7598,11 +7598,12 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
        unsigned long pfn, iter, found;
 
        /*
-        * For avoiding noise data, lru_add_drain_all() should be called
-        * If ZONE_MOVABLE, the zone never contains unmovable pages
+        * TODO we could make this much more efficient by not checking every
+        * page in the range if we know all of them are in MOVABLE_ZONE and
+        * that the movable zone guarantees that pages are migratable but
+        * the later is not the case right now unfortunatelly. E.g. movablecore
+        * can still lead to having bootmem allocations in zone_movable.
         */
-       if (zone_idx(zone) == ZONE_MOVABLE)
-               return false;
 
        /*
         * CMA allocations (alloc_contig_range) really need to mark isolate
@@ -7623,7 +7624,7 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                page = pfn_to_page(check);
 
                if (PageReserved(page))
-                       return true;
+                       goto unmovable;
 
                /*
                 * Hugepages are not in LRU lists, but they're movable.
@@ -7673,9 +7674,12 @@ bool has_unmovable_pages(struct zone *zone, struct page *page, int count,
                 * page at boot.
                 */
                if (found > count)
-                       return true;
+                       goto unmovable;
        }
        return false;
+unmovable:
+       WARN_ON_ONCE(zone_idx(zone) == ZONE_MOVABLE);
+       return true;
 }
 
 bool is_pageblock_removable_nolock(struct page *page)
index cc2cf04d9018ad0c546648dfa6cb8167082bbc99..78a015fcec3b1efe29b56580eb3d4dc510243f6a 100644 (file)
@@ -3112,6 +3112,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
        unsigned long *frontswap_map = NULL;
        struct page *page = NULL;
        struct inode *inode = NULL;
+       bool inced_nr_rotate_swap = false;
 
        if (swap_flags & ~SWAP_FLAGS_VALID)
                return -EINVAL;
@@ -3215,8 +3216,10 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
                        cluster = per_cpu_ptr(p->percpu_cluster, cpu);
                        cluster_set_null(&cluster->index);
                }
-       } else
+       } else {
                atomic_inc(&nr_rotate_swap);
+               inced_nr_rotate_swap = true;
+       }
 
        error = swap_cgroup_swapon(p->type, maxpages);
        if (error)
@@ -3307,6 +3310,8 @@ bad_swap:
        vfree(swap_map);
        kvfree(cluster_info);
        kvfree(frontswap_map);
+       if (inced_nr_rotate_swap)
+               atomic_dec(&nr_rotate_swap);
        if (swap_file) {
                if (inode && S_ISREG(inode->i_mode)) {
                        inode_unlock(inode);
index a11d3d89f0120a17c26f41a0559b6c40ebbbc6ca..a35f597e8c8bf4f15ad0f01aff29849d2bebe36f 100644 (file)
@@ -1536,7 +1536,7 @@ out:
 
        if (!ret && primary_if)
                *primary_if = hard_iface;
-       else
+       else if (hard_iface)
                batadv_hardif_put(hard_iface);
 
        return ret;
index 0225616d5771d0986127322142fc591780fc25b0..3986551397caa5ffb6ba7338eeb4769c8b8f99fb 100644 (file)
@@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
        struct batadv_orig_node_vlan *vlan;
        u8 *tt_change_ptr;
 
-       rcu_read_lock();
+       spin_lock_bh(&orig_node->vlan_list_lock);
        hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
                num_vlan++;
                num_entries += atomic_read(&vlan->tt.num_entries);
@@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
        *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
 
 out:
-       rcu_read_unlock();
+       spin_unlock_bh(&orig_node->vlan_list_lock);
        return tvlv_len;
 }
 
@@ -931,15 +931,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
        struct batadv_tvlv_tt_vlan_data *tt_vlan;
        struct batadv_softif_vlan *vlan;
        u16 num_vlan = 0;
-       u16 num_entries = 0;
+       u16 vlan_entries = 0;
+       u16 total_entries = 0;
        u16 tvlv_len;
        u8 *tt_change_ptr;
        int change_offset;
 
-       rcu_read_lock();
+       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+               vlan_entries = atomic_read(&vlan->tt.num_entries);
+               if (vlan_entries < 1)
+                       continue;
+
                num_vlan++;
-               num_entries += atomic_read(&vlan->tt.num_entries);
+               total_entries += vlan_entries;
        }
 
        change_offset = sizeof(**tt_data);
@@ -947,7 +952,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
 
        /* if tt_len is negative, allocate the space needed by the full table */
        if (*tt_len < 0)
-               *tt_len = batadv_tt_len(num_entries);
+               *tt_len = batadv_tt_len(total_entries);
 
        tvlv_len = *tt_len;
        tvlv_len += change_offset;
@@ -964,6 +969,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
 
        tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
        hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+               vlan_entries = atomic_read(&vlan->tt.num_entries);
+               if (vlan_entries < 1)
+                       continue;
+
                tt_vlan->vid = htons(vlan->vid);
                tt_vlan->crc = htonl(vlan->tt.crc);
 
@@ -974,7 +983,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
        *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
 
 out:
-       rcu_read_unlock();
+       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
        return tvlv_len;
 }
 
@@ -1538,6 +1547,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
  *  handled by a given originator
  * @entry: the TT global entry to check
  * @orig_node: the originator to search in the list
+ * @flags: a pointer to store TT flags for the given @entry received
+ *  from @orig_node
  *
  * find out if an orig_node is already in the list of a tt_global_entry.
  *
@@ -1545,7 +1556,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
  */
 static bool
 batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
-                               const struct batadv_orig_node *orig_node)
+                               const struct batadv_orig_node *orig_node,
+                               u8 *flags)
 {
        struct batadv_tt_orig_list_entry *orig_entry;
        bool found = false;
@@ -1553,6 +1565,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
        orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
        if (orig_entry) {
                found = true;
+
+               if (flags)
+                       *flags = orig_entry->flags;
+
                batadv_tt_orig_list_entry_put(orig_entry);
        }
 
@@ -1731,7 +1747,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
                        if (!(common->flags & BATADV_TT_CLIENT_TEMP))
                                goto out;
                        if (batadv_tt_global_entry_has_orig(tt_global_entry,
-                                                           orig_node))
+                                                           orig_node, NULL))
                                goto out_remove;
                        batadv_tt_global_del_orig_list(tt_global_entry);
                        goto add_orig_entry;
@@ -2880,23 +2896,46 @@ unlock:
 }
 
 /**
- * batadv_tt_local_valid() - verify that given tt entry is a valid one
+ * batadv_tt_local_valid() - verify local tt entry and get flags
  * @entry_ptr: to be checked local tt entry
  * @data_ptr: not used but definition required to satisfy the callback prototype
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given local TT entry. If it is, then the provided
+ * flags pointer is updated.
  *
  * Return: true if the entry is a valid, false otherwise.
  */
-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
+static bool batadv_tt_local_valid(const void *entry_ptr,
+                                 const void *data_ptr,
+                                 u8 *flags)
 {
        const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
 
        if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
                return false;
+
+       if (flags)
+               *flags = tt_common_entry->flags;
+
        return true;
 }
 
+/**
+ * batadv_tt_global_valid() - verify global tt entry and get flags
+ * @entry_ptr: to be checked global tt entry
+ * @data_ptr: an orig_node object (may be NULL)
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given global TT entry. If it is, then the provided
+ * flags pointer is updated either with the common (summed) TT flags if data_ptr
+ * is NULL or the specific, per originator TT flags otherwise.
+ *
+ * Return: true if the entry is a valid, false otherwise.
+ */
 static bool batadv_tt_global_valid(const void *entry_ptr,
-                                  const void *data_ptr)
+                                  const void *data_ptr,
+                                  u8 *flags)
 {
        const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
        const struct batadv_tt_global_entry *tt_global_entry;
@@ -2910,7 +2949,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
                                       struct batadv_tt_global_entry,
                                       common);
 
-       return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
+       return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
+                                              flags);
 }
 
 /**
@@ -2920,25 +2960,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
  * @hash: hash table containing the tt entries
  * @tt_len: expected tvlv tt data buffer length in number of bytes
  * @tvlv_buff: pointer to the buffer to fill with the TT data
- * @valid_cb: function to filter tt change entries
+ * @valid_cb: function to filter tt change entries and to return TT flags
  * @cb_data: data passed to the filter function as argument
+ *
+ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
+ * is not provided then this becomes a no-op.
  */
 static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
                                    struct batadv_hashtable *hash,
                                    void *tvlv_buff, u16 tt_len,
                                    bool (*valid_cb)(const void *,
-                                                    const void *),
+                                                    const void *,
+                                                    u8 *flags),
                                    void *cb_data)
 {
        struct batadv_tt_common_entry *tt_common_entry;
        struct batadv_tvlv_tt_change *tt_change;
        struct hlist_head *head;
        u16 tt_tot, tt_num_entries = 0;
+       u8 flags;
+       bool ret;
        u32 i;
 
        tt_tot = batadv_tt_entries(tt_len);
        tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
 
+       if (!valid_cb)
+               return;
+
        rcu_read_lock();
        for (i = 0; i < hash->size; i++) {
                head = &hash->table[i];
@@ -2948,11 +2997,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
                        if (tt_tot == tt_num_entries)
                                break;
 
-                       if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
+                       ret = valid_cb(tt_common_entry, cb_data, &flags);
+                       if (!ret)
                                continue;
 
                        ether_addr_copy(tt_change->addr, tt_common_entry->addr);
-                       tt_change->flags = tt_common_entry->flags;
+                       tt_change->flags = flags;
                        tt_change->vid = htons(tt_common_entry->vid);
                        memset(tt_change->reserved, 0,
                               sizeof(tt_change->reserved));
index 84cd4e3fd01b1dec5ed4234291dde60d4f1d1d61..0d56e36a6db7b77dcdeb9697dd81bf62895e6e4c 100644 (file)
@@ -283,9 +283,7 @@ int dccp_disconnect(struct sock *sk, int flags)
 
        dccp_clear_xmit_timers(sk);
        ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
-       ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
        dp->dccps_hc_rx_ccid = NULL;
-       dp->dccps_hc_tx_ccid = NULL;
 
        __skb_queue_purge(&sk->sk_receive_queue);
        __skb_queue_purge(&sk->sk_write_queue);
index 4d622112bf95fabd9d0e87c64f1e27138a3c1556..e66172aaf241874ea5b4011c4d1ea3ed00ee8c3f 100644 (file)
@@ -649,6 +649,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
        [RTA_ENCAP]             = { .type = NLA_NESTED },
        [RTA_UID]               = { .type = NLA_U32 },
        [RTA_MARK]              = { .type = NLA_U32 },
+       [RTA_TABLE]             = { .type = NLA_U32 },
 };
 
 static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
index 5ad2d8ed3a3fe2aa51d814af442df7ff5e074d3e..57bbb060faaf834bedabb8c23175a126df5910a6 100644 (file)
@@ -505,8 +505,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
        int err;
        int copied;
 
-       WARN_ON_ONCE(sk->sk_family == AF_INET6);
-
        err = -EAGAIN;
        skb = sock_dequeue_err_skb(sk);
        if (!skb)
index 4fe97723b53f4deb5ebbb1d7633ceb1b4efc3af3..30221701614c599d380229c69b83558537c69de8 100644 (file)
@@ -43,7 +43,10 @@ mr_table_alloc(struct net *net, u32 id,
        write_pnet(&mrt->net, net);
 
        mrt->ops = *ops;
-       rhltable_init(&mrt->mfc_hash, mrt->ops.rht_params);
+       if (rhltable_init(&mrt->mfc_hash, mrt->ops.rht_params)) {
+               kfree(mrt);
+               return NULL;
+       }
        INIT_LIST_HEAD(&mrt->mfc_cache_list);
        INIT_LIST_HEAD(&mrt->mfc_unres_queue);
 
index 0f6c9ca590628ccfaff872ec89c7e5bc9149424e..5b5b0f95ffd13ecef6feeab6a0f2d64e36ba6561 100644 (file)
@@ -401,7 +401,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
 
 static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
                               struct sta_info *sta,
-                              struct ieee802_11_elems *elems, bool insert)
+                              struct ieee802_11_elems *elems)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
@@ -447,7 +447,7 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
                sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
        }
 
-       if (insert)
+       if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
                rate_control_rate_init(sta);
        else
                rate_control_rate_update(local, sband, sta, changed);
@@ -551,7 +551,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
        rcu_read_lock();
        sta = sta_info_get(sdata, addr);
        if (sta) {
-               mesh_sta_info_init(sdata, sta, elems, false);
+               mesh_sta_info_init(sdata, sta, elems);
        } else {
                rcu_read_unlock();
                /* can't run atomic */
@@ -561,7 +561,7 @@ mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
                        return NULL;
                }
 
-               mesh_sta_info_init(sdata, sta, elems, true);
+               mesh_sta_info_init(sdata, sta, elems);
 
                if (sta_info_insert_rcu(sta))
                        return NULL;
index e9422fe45179363ef1d7a1c5c406a6d058f61e29..acb7b86574cd3d6f13790550c00f11616caff2e3 100644 (file)
@@ -2911,7 +2911,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
                if (unlikely(offset < 0))
                        goto out_free;
        } else if (reserve) {
-               skb_push(skb, reserve);
+               skb_reserve(skb, -reserve);
        }
 
        /* Returns -EFAULT on error */
index 963e4bf0aab8ae23d999305208c757fbc0f49ebe..a57e112d9b3ee517f1502f466a23cf8ea3099ac3 100644 (file)
@@ -1588,7 +1588,7 @@ int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts,
                return ret;
        ok_count = ret;
 
-       if (!exts)
+       if (!exts || ok_count)
                return ok_count;
        ret = tc_exts_setup_cb_egdev_call(exts, type, type_data, err_stop);
        if (ret < 0)
index 42247110d842e75d61068ad20d577d8dc6dd4263..0cd2e764f47ff0874438301324de25e4bf33dd95 100644 (file)
@@ -1006,7 +1006,7 @@ static const struct proto_ops inet6_seqpacket_ops = {
        .owner             = THIS_MODULE,
        .release           = inet6_release,
        .bind              = inet6_bind,
-       .connect           = inet_dgram_connect,
+       .connect           = sctp_inet_connect,
        .socketpair        = sock_no_socketpair,
        .accept            = inet_accept,
        .getname           = sctp_getname,
index d685f84567624aedfb043c9ba56d3977849f16e5..6bf0a99718884a4d4952ab530c43b769bb5dafbb 100644 (file)
@@ -1012,7 +1012,7 @@ static const struct proto_ops inet_seqpacket_ops = {
        .owner             = THIS_MODULE,
        .release           = inet_release,      /* Needs to be wrapped... */
        .bind              = inet_bind,
-       .connect           = inet_dgram_connect,
+       .connect           = sctp_inet_connect,
        .socketpair        = sock_no_socketpair,
        .accept            = inet_accept,
        .getname           = inet_getname,      /* Semantics are different.  */
index 80835ac26d2c3ce6559f75aaaa0b315fb77d9adf..ae7e7c606f72187aaaf3b4c25bf2f0981eec1fae 100644 (file)
@@ -1086,7 +1086,7 @@ out:
  */
 static int __sctp_connect(struct sock *sk,
                          struct sockaddr *kaddrs,
-                         int addrs_size,
+                         int addrs_size, int flags,
                          sctp_assoc_t *assoc_id)
 {
        struct net *net = sock_net(sk);
@@ -1104,7 +1104,6 @@ static int __sctp_connect(struct sock *sk,
        union sctp_addr *sa_addr = NULL;
        void *addr_buf;
        unsigned short port;
-       unsigned int f_flags = 0;
 
        sp = sctp_sk(sk);
        ep = sp->ep;
@@ -1254,13 +1253,7 @@ static int __sctp_connect(struct sock *sk,
        sp->pf->to_sk_daddr(sa_addr, sk);
        sk->sk_err = 0;
 
-       /* in-kernel sockets don't generally have a file allocated to them
-        * if all they do is call sock_create_kern().
-        */
-       if (sk->sk_socket->file)
-               f_flags = sk->sk_socket->file->f_flags;
-
-       timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
+       timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
 
        if (assoc_id)
                *assoc_id = asoc->assoc_id;
@@ -1348,7 +1341,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
                                      sctp_assoc_t *assoc_id)
 {
        struct sockaddr *kaddrs;
-       int err = 0;
+       int err = 0, flags = 0;
 
        pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",
                 __func__, sk, addrs, addrs_size);
@@ -1367,7 +1360,13 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
        if (err)
                goto out_free;
 
-       err = __sctp_connect(sk, kaddrs, addrs_size, assoc_id);
+       /* in-kernel sockets don't generally have a file allocated to them
+        * if all they do is call sock_create_kern().
+        */
+       if (sk->sk_socket->file)
+               flags = sk->sk_socket->file->f_flags;
+
+       err = __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id);
 
 out_free:
        kvfree(kaddrs);
@@ -4397,16 +4396,26 @@ out_nounlock:
  * len: the size of the address.
  */
 static int sctp_connect(struct sock *sk, struct sockaddr *addr,
-                       int addr_len)
+                       int addr_len, int flags)
 {
-       int err = 0;
+       struct inet_sock *inet = inet_sk(sk);
        struct sctp_af *af;
+       int err = 0;
 
        lock_sock(sk);
 
        pr_debug("%s: sk:%p, sockaddr:%p, addr_len:%d\n", __func__, sk,
                 addr, addr_len);
 
+       /* We may need to bind the socket. */
+       if (!inet->inet_num) {
+               if (sk->sk_prot->get_port(sk, 0)) {
+                       release_sock(sk);
+                       return -EAGAIN;
+               }
+               inet->inet_sport = htons(inet->inet_num);
+       }
+
        /* Validate addr_len before calling common connect/connectx routine. */
        af = sctp_get_af_specific(addr->sa_family);
        if (!af || addr_len < af->sockaddr_len) {
@@ -4415,13 +4424,25 @@ static int sctp_connect(struct sock *sk, struct sockaddr *addr,
                /* Pass correct addr len to common routine (so it knows there
                 * is only one address being passed.
                 */
-               err = __sctp_connect(sk, addr, af->sockaddr_len, NULL);
+               err = __sctp_connect(sk, addr, af->sockaddr_len, flags, NULL);
        }
 
        release_sock(sk);
        return err;
 }
 
+int sctp_inet_connect(struct socket *sock, struct sockaddr *uaddr,
+                     int addr_len, int flags)
+{
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
+
+       if (uaddr->sa_family == AF_UNSPEC)
+               return -EOPNOTSUPP;
+
+       return sctp_connect(sock->sk, uaddr, addr_len, flags);
+}
+
 /* FIXME: Write comments. */
 static int sctp_disconnect(struct sock *sk, int flags)
 {
@@ -8724,7 +8745,6 @@ struct proto sctp_prot = {
        .name        =  "SCTP",
        .owner       =  THIS_MODULE,
        .close       =  sctp_close,
-       .connect     =  sctp_connect,
        .disconnect  =  sctp_disconnect,
        .accept      =  sctp_accept,
        .ioctl       =  sctp_ioctl,
@@ -8767,7 +8787,6 @@ struct proto sctpv6_prot = {
        .name           = "SCTPv6",
        .owner          = THIS_MODULE,
        .close          = sctp_close,
-       .connect        = sctp_connect,
        .disconnect     = sctp_disconnect,
        .accept         = sctp_accept,
        .ioctl          = sctp_ioctl,
index a052693c2e852b856f96d304cb97b6ddd0ff5319..7c5135a92d764448bac44bff8c4107cba7ea5c1c 100644 (file)
@@ -15555,7 +15555,8 @@ void cfg80211_ft_event(struct net_device *netdev,
        if (!ft_event->target_ap)
                return;
 
-       msg = nlmsg_new(100 + ft_event->ric_ies_len, GFP_KERNEL);
+       msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
+                       GFP_KERNEL);
        if (!msg)
                return;
 
index ac3e12c32aa30053a110d6a46f5bb813d660c8b6..5fcec5c94eb727cafd5a5168f7634eaec59b11d1 100644 (file)
@@ -916,6 +916,9 @@ int reg_query_regdb_wmm(char *alpha2, int freq, u32 *dbptr,
        const struct fwdb_header *hdr = regdb;
        const struct fwdb_country *country;
 
+       if (!regdb)
+               return -ENODATA;
+
        if (IS_ERR(regdb))
                return PTR_ERR(regdb);
 
index e16d6713f2368473d96eaec321fda1685cb3cac5..2d42eb9cd1a5639637df3f1fec35b4216d1c5fa5 100755 (executable)
@@ -5041,7 +5041,7 @@ sub process {
                                $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
                                $tmp_stmt =~ s/\#+\s*$arg\b//g;
                                $tmp_stmt =~ s/\b$arg\s*\#\#//g;
-                               my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g;
+                               my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
                                if ($use_cnt > 1) {
                                        CHK("MACRO_ARG_REUSE",
                                            "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
index dc87728c5b745e5a8e36e7adfc853470ae91ab7f..0ddcae4958381758ab6189ca6ad7a97375ddf184 100644 (file)
@@ -592,7 +592,7 @@ static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
        else
                timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
        snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
-                         SNDRV_TIMER_EVENT_CONTINUE);
+                         SNDRV_TIMER_EVENT_PAUSE);
  unlock:
        spin_unlock_irqrestore(&timer->lock, flags);
        return result;
@@ -614,7 +614,7 @@ static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop)
                list_del_init(&timeri->ack_list);
                list_del_init(&timeri->active_list);
                snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
-                                 SNDRV_TIMER_EVENT_CONTINUE);
+                                 SNDRV_TIMER_EVENT_PAUSE);
                spin_unlock(&timeri->timer->lock);
        }
        spin_unlock_irqrestore(&slave_active_lock, flags);
index 321e78baa63ca830332f7be3221cf4b999c2a4fe..9bd935216c1866677841c0aaa6fe943a7d7e313b 100644 (file)
@@ -622,8 +622,10 @@ snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
 {
        return snd_hdac_check_power_state(&codec->core, nid, target_state);
 }
-static inline bool snd_hda_sync_power_state(struct hda_codec *codec,
-                          hda_nid_t nid, unsigned int target_state)
+
+static inline unsigned int snd_hda_sync_power_state(struct hda_codec *codec,
+                                                   hda_nid_t nid,
+                                                   unsigned int target_state)
 {
        return snd_hdac_sync_power_state(&codec->core, nid, target_state);
 }
index 6c645eb77d4218fd102968fb2a24b19350e3edd9..ee820fcc29b0d3c201cbd63e56daa2392e89bcbf 100644 (file)
@@ -252,6 +252,13 @@ void idr_checks(void)
        idr_remove(&idr, 3);
        idr_remove(&idr, 0);
 
+       assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == 0);
+       idr_remove(&idr, 1);
+       for (i = 1; i < RADIX_TREE_MAP_SIZE; i++)
+               assert(idr_alloc(&idr, DUMMY_PTR, 0, 0, GFP_KERNEL) == i);
+       idr_remove(&idr, 1 << 30);
+       idr_destroy(&idr);
+
        for (i = INT_MAX - 3UL; i < INT_MAX + 1UL; i++) {
                struct item *item = item_create(i, 0);
                assert(idr_alloc(&idr, item, i, i + 10, GFP_KERNEL) == i);
index 983dd25d49f452d91191191188634beb8b47dc26..1eefe211a4a88a3dfbac5be585932384061b9edd 100644 (file)
@@ -5,3 +5,5 @@ CONFIG_BPF_EVENTS=y
 CONFIG_TEST_BPF=m
 CONFIG_CGROUP_BPF=y
 CONFIG_NETDEVSIM=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_SCH_INGRESS=y
index 6a75a3ea44adb5bde3cc1c00000a96307f88471e..7ba089b33e8b8248ec08d8421a582be66c9f7e87 100644 (file)
@@ -7,3 +7,8 @@ CONFIG_NET_L3_MASTER_DEV=y
 CONFIG_IPV6=y
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_VETH=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_NET_IPVTI=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_IPV6_VTI=y
+CONFIG_DUMMY=y
index 365c32e841897e0c43e8372a21086d1ccabe35c5..c9f478b40996d3bc0037c8e3b08dc477725a85d0 100644 (file)
@@ -23,6 +23,8 @@
 #include <unistd.h>
 #include <numa.h>
 
+#include "../kselftest.h"
+
 static const int PORT = 8888;
 
 static void build_rcv_group(int *rcv_fd, size_t len, int family, int proto)
@@ -229,7 +231,7 @@ int main(void)
        int *rcv_fd, nodes;
 
        if (numa_available() < 0)
-               error(1, errno, "no numa api support");
+               ksft_exit_skip("no numa api support\n");
 
        nodes = numa_max_node() + 1;